Added GDSII parser. Component/Polygon reorganisation.

* New: In CRL, implement a GDSII parser. The complete syntax is supported,
    but only a few subset is really taken into account. It is intended to
    load the layout of standard cells only. The interface of the cell is
    provided through a LEF file and it complete layout through the GDSII.
      The loader work in a Library way. It takes a Hurricane library as
    argument and search in the GDSII library structures with a name
    matching the Cell of the library and complete them.
* Change: In Hurricane::Component, put the Contour methods at Component
    level so we can use them in a generic way in the CellWidget drawing
    primitives.
* New: Hurricane::Rectilinear polygon, for small rectlinear polygons.
    Should be less than 100 vertexes. For bigger ones, use Polygon
    which allows slanted egdes.
* Bug: In CRL, freepdk_45/technology.conf, there seems to be an incoherency
    bettween the GDSII layer numbers as defined in the Cadence FreeePDK45.tf
    file and the one used in the supplied layout of the GDSII cells.
      For now, we align on the GDSII cells to get nice layouts, but it
    has to checked.
This commit is contained in:
Jean-Paul Chaput 2018-05-20 15:47:34 +02:00
parent 4a65a8d4e7
commit ea16b5a556
25 changed files with 2280 additions and 313 deletions

View File

@ -233,51 +233,71 @@ layersExtensionsTable = \
)
gdsLayersTable = \
( ("nWell" , "NTUB" , 5)
, ("nImplant", "NPLUS" , 23)
, ("pImplant", "PPLUS" , 24)
, ("active" , "DIFF" , 10)
, ("poly" , "POLY1" , 20)
, ("cut0" , "CONT" , 34)
, ("metal1" , "MET1" , 35)
, ("cut1" , "VIA1" , 36)
, ("metal2" , "MET2" , 37)
, ("metcap" , "METCAP" , 55)
, ("cut2" , "VIA2" , 38)
, ("metal3" , "MET3" , 39)
, ("cut3" , "VIA3" , 41)
, ("metal4" , "MET4" , 42)
)
# Table guessed from the Cadence configuration files:
# FreePDK45/ncsu_basekit/techfile/FreePDK45.tf
#
# Format of an entry in the table:
# (Symbolic_Name, CIF_Name, GDSII_Number)
#gdsLayersTable = \
# ( ("pWell" , "CWN" , 2, 0)
# , ("nWell" , "CWP" , 3, 0)
# , ("active" , "CAA" , 1, 0)
# , ("pImplant", "CSP" , 5, 0)
# , ("nImplant", "CSN" , 4, 0)
# , ("poly" , "CPG" , 9, 0)
# , ("cut0" , "CCC" , 10, 0)
# , ("metal1" , "CM1" , 11, 0)
# , ("cut1" , "CV1" , 12, 0)
# , ("metal2" , "CM2" , 13, 0)
# , ("cut2" , "CV2" , 14, 0)
# , ("metal3" , "CM3" , 15, 0)
# , ("cut3" , "CV3" , 16, 0)
# , ("metal4" , "CM4" , 17, 0)
# , ("cut4" , "CV4" , 18, 0)
# , ("metal5" , "CM5" , 19, 0)
# , ("cut5" , "CV5" , 20, 0)
# , ("metal6" , "CM6" , 21, 0)
# , ("cut6" , "CV6" , 22, 0)
# , ("metal7" , "CM7" , 23, 0)
# , ("cut7" , "CV7" , 24, 0)
# , ("metal8" , "CM8" , 25, 0)
# , ("cut8" , "CV8" , 26, 0)
# , ("metal9" , "CM9" , 27, 0)
# , ("cut9" , "CV9" , 28, 0)
# , ("metal10" , "CM10" , 29, 0)
# )
# Table guessed from the GDSII layouts of the cells.
# FreePDK45/osu_soc/lib/source/gds/*.gds
#
# Format of an entry in the table:
# (Symbolic_Name, CIF_Name, GDSII_Number)
gdsLayersTable = \
( ("pWell" , "CWN" , 2, 0)
, ("nWell" , "CWP" , 3, 0)
, ("active" , "CAA" , 1, 0)
, ("pImplant", "CSP" , 5, 0)
, ("nImplant", "CSN" , 4, 0)
, ("poly" , "CPG" , 9, 0)
, ("cut0" , "CCC" , 10, 0)
, ("metal1" , "CM1" , 11, 0)
, ("cut1" , "CV1" , 12, 0)
, ("metal2" , "CM2" , 13, 0)
, ("cut2" , "CV2" , 14, 0)
, ("metal3" , "CM3" , 15, 0)
, ("cut3" , "CV3" , 16, 0)
, ("metal4" , "CM4" , 17, 0)
, ("cut4" , "CV4" , 18, 0)
, ("metal5" , "CM5" , 19, 0)
, ("cut5" , "CV5" , 20, 0)
, ("metal6" , "CM6" , 21, 0)
, ("cut6" , "CV6" , 22, 0)
, ("metal7" , "CM7" , 23, 0)
, ("cut7" , "CV7" , 24, 0)
, ("metal8" , "CM8" , 25, 0)
, ("cut8" , "CV8" , 26, 0)
, ("metal9" , "CM9" , 27, 0)
, ("cut9" , "CV9" , 28, 0)
, ("metal10" , "CM10" , 29, 0)
, ("nWell" , "CWP" , 1, 0)
, ("active" , "CAA" , 5, 0)
, ("pImplant", "CSP" , 8, 0)
, ("nImplant", "CSN" , 7, 0)
, ("poly" , "CPG" , 15, 0)
, ("cut0" , "CCC" , 16, 0)
, ("metal1" , "CM1" , 21, 0)
, ("cut1" , "CV1" , 22, 0)
, ("metal2" , "CM2" , 23, 0)
, ("cut2" , "CV2" , 24, 0)
, ("metal3" , "CM3" , 25, 0)
, ("cut3" , "CV3" , 26, 0)
, ("metal4" , "CM4" , 27, 0)
, ("cut4" , "CV4" , 28, 0)
, ("metal5" , "CM5" , 29, 0)
, ("cut5" , "CV5" , 30, 0)
, ("metal6" , "CM6" , 31, 0)
, ("cut6" , "CV6" , 32, 0)
, ("metal7" , "CM7" , 33, 0)
, ("cut7" , "CV7" , 34, 0)
, ("metal8" , "CM8" , 35, 0)
, ("cut8" , "CV8" , 36, 0)
, ("metal9" , "CM9" , 37, 0)
, ("cut9" , "CV9" , 38, 0)
, ("metal10" , "CM10" , 39, 0)
)

View File

@ -117,6 +117,7 @@
alliance/ap/ApDriver.cpp
)
set ( gds_cpps gds/GdsDriver.cpp
gds/GdsParser.cpp
)
set ( cif_cpps cif/CifDriver.cpp
)

View File

@ -22,17 +22,20 @@
namespace Hurricane {
class Cell;
class Library;
}
namespace CRL {
using Hurricane::Cell;
using Hurricane::Library;
class Gds {
public:
static bool save ( Cell* );
static bool load ( Library*, std::string gdsPath );
};

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,7 @@
PyAcmSigda.cpp
PyIspd05.cpp
PyBlif.cpp
PyGds.cpp
PyLefImport.cpp
)
set( pyIncludes crlcore/PyBanner.h
@ -61,6 +62,7 @@
crlcore/PyAcmSigda.h
crlcore/PyIspd05.h
crlcore/PyBlif.h
crlcore/PyGds.h
crlcore/PyLefImport.h
)
set( depLibs crlcore

View File

@ -32,6 +32,7 @@
#include "crlcore/PyAcmSigda.h"
#include "crlcore/PyIspd05.h"
#include "crlcore/PyBlif.h"
#include "crlcore/PyGds.h"
#include "crlcore/PyLefImport.h"
#include "crlcore/VhdlEntity.h"
@ -121,6 +122,7 @@ extern "C" {
PyAcmSigda_LinkPyType ();
PyIspd05_LinkPyType ();
PyBlif_LinkPyType ();
PyGds_LinkPyType ();
PyLefImport_LinkPyType ();
PYTYPE_READY ( Banner );
@ -140,6 +142,7 @@ extern "C" {
PYTYPE_READY ( AcmSigda );
PYTYPE_READY ( Ispd05 );
PYTYPE_READY ( Blif );
PYTYPE_READY ( Gds );
PYTYPE_READY ( LefImport );
// Identifier string can take up to 10 characters.
@ -191,6 +194,8 @@ extern "C" {
PyModule_AddObject ( module, "Ispd05", (PyObject*)&PyTypeIspd05 );
Py_INCREF ( &PyTypeBlif );
PyModule_AddObject ( module, "Blif", (PyObject*)&PyTypeBlif );
Py_INCREF ( &PyTypeGds );
PyModule_AddObject ( module, "Gds", (PyObject*)&PyTypeGds );
Py_INCREF ( &PyTypeLefImport );
PyModule_AddObject ( module, "LefImport", (PyObject*)&PyTypeLefImport );

144
crlcore/src/pyCRL/PyGds.cpp Normal file
View File

@ -0,0 +1,144 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyGds.cpp" |
// +-----------------------------------------------------------------+
#include "crlcore/PyGds.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/isobar/PyLibrary.h"
#include <string>
#include <sstream>
namespace CRL {
using std::cerr;
using std::endl;
using std::hex;
using std::string;
using std::ostringstream;
using Hurricane::tab;
using Hurricane::Exception;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Isobar::ProxyProperty;
using Isobar::ProxyError;
using Isobar::ConstructorError;
using Isobar::HurricaneError;
using Isobar::HurricaneWarning;
using Isobar::ParseOneArg;
using Isobar::ParseTwoArg;
using Isobar::__cs;
using Isobar::PyCell;
using Isobar::PyTypeCell;
using Isobar::PyCell_Link;
using Isobar::PyLibrary;
using Isobar::PyTypeLibrary;
using Isobar::PyLibrary_Link;
extern "C" {
#if defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PyGds" Python Module Code Part |
// +=================================================================+
static PyObject* PyGds_save ( PyObject*, PyObject* args )
{
cdebug_log(30,0) << "PyGds_save()" << endl;
Cell* cell = NULL;
HTRY
PyObject* pyCell = NULL;
if (PyArg_ParseTuple( args, "O:Gds.save", &pyCell )) {
if (IsPyCell(pyCell)) {
Gds::save( PYCELL_O(pyCell) );
} else {
PyErr_SetString( ConstructorError, "Gds.load(): Bad parameter type (not a Cell)." );
return NULL;
}
} else {
PyErr_SetString( ConstructorError, "Gds.load(): Bad number of parameters." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyGds_load ( PyObject*, PyObject* args )
{
cdebug_log(30,0) << "PyGds_load()" << endl;
Library* library = NULL;
char* path = NULL;
HTRY
PyObject* pyLibrary = NULL;
if (PyArg_ParseTuple( args, "Os:Gds.load", &pyLibrary, &path )) {
if (IsPyLibrary(pyLibrary)) {
Gds::load( PYLIBRARY_O(pyLibrary), string(path) );
} else {
PyErr_SetString( ConstructorError, "Gds.load(): Bad parameter type (not a Library)." );
return NULL;
}
} else {
PyErr_SetString( ConstructorError, "Gds.load(): Bad number of parameters." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
// Standart Destroy (Attribute).
PyMethodDef PyGds_Methods[] =
{ { "save" , (PyCFunction)PyGds_save , METH_VARARGS|METH_STATIC
, "Save a complete Gds design." }
, { "load" , (PyCFunction)PyGds_load , METH_VARARGS|METH_STATIC
, "Load a Gds layout inside a Cell (cumulative)." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
NoObjectDeleteMethod(Gds)
PyTypeObjectLinkPyTypeWithoutObject(Gds,Gds)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyGds" Shared Library Code Part |
// +=================================================================+
// Type Definition.
PyTypeObjectDefinitionsOfModule(CRL,Gds)
#endif // End of Shared Library Code Part.
} // extern "C".
} // CRL namespace.

View File

@ -0,0 +1,55 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/PyGds.h" |
// +-----------------------------------------------------------------+
#ifndef CRL_PY_GDS_H
#define CRL_PY_GDS_H
#include "hurricane/isobar/PyHurricane.h"
#include "crlcore/Gds.h"
namespace CRL {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyGds".
typedef struct {
PyObject_HEAD
} PyGds;
// -------------------------------------------------------------------
// Functions & Types exported to "PyCRL.ccp".
extern PyTypeObject PyTypeGds;
extern PyMethodDef PyGds_Methods[];
extern void PyGds_LinkPyType();
#define IsPyGds(v) ( (v)->ob_type == &PyTypeGds )
#define PY_GDS(v) ( (PyGds*)(v) )
} // extern "C".
} // Hurricane namespace.
#endif // CRL_PY_GDS_H

View File

@ -76,8 +76,7 @@ def buildDiagonals ( editor ):
UpdateSession.close()
#AllianceFramework.get().saveCell( cell, Catalog.State.Views )
# No saving as we don't have a GDSII driver (yet).
Gds.save( cell )
return

View File

@ -44,11 +44,11 @@ def buildFulladder ( editor ):
vss = Net.create( fulladder, "vss" )
vss.setExternal( True )
vss.setGlobal ( True )
vdd = Net.create( fulladder, "vdd" )
vdd.setExternal( True )
vdd.setGlobal ( True )
cin = Net.create( fulladder, "cin" )
cin.setExternal( True )
xr2_2.getPlug( xr2_x2.getNet('i0') ).setNet( cin )
@ -72,11 +72,11 @@ def buildFulladder ( editor ):
carry_1 = Net.create( fulladder, 'carry_1' )
a2_1.getPlug( a2_x2.getNet('q' ) ).setNet( carry_1 )
o2_1.getPlug( o2_x2.getNet('i1') ).setNet( carry_1 )
carry_2 = Net.create( fulladder, 'carry_2' )
a2_2.getPlug( a2_x2.getNet('q' ) ).setNet( carry_2 )
o2_1.getPlug( o2_x2.getNet('i0') ).setNet( carry_2 )
sout = Net.create( fulladder, 'sout' )
sout.setExternal( True )
xr2_2.getPlug( xr2_x2.getNet('q') ).setNet( sout )
@ -90,56 +90,56 @@ def buildFulladder ( editor ):
, toDbU(0.0)
, Transformation.Orientation.ID ) )
a2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed a2_1' )
#doBreak( 1, 'Placed a2_1' )
xr2_1.setTransformation( Transformation( toDbU( 0.0)
, toDbU(100.0)
, Transformation.Orientation.MY ) )
xr2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed xr2_1' )
#doBreak( 1, 'Placed xr2_1' )
a2_2.setTransformation( Transformation( toDbU(25.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
a2_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed a2_2' )
#doBreak( 1, 'Placed a2_2' )
xr2_2.setTransformation( Transformation( toDbU( 45.0)
, toDbU(100.0)
, Transformation.Orientation.MY ) )
xr2_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed xr2_2' )
#doBreak( 1, 'Placed xr2_2' )
o2_1.setTransformation( Transformation( toDbU(65.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
o2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed o2_1' )
#doBreak( 1, 'Placed o2_1' )
# Add filler cells.
tie_x0 = af.getCell( 'tie_x0', Catalog.State.Views )
rowend_x0 = af.getCell( 'rowend_x0', Catalog.State.Views )
filler_1 = Instance.create( fulladder, 'filler_1', tie_x0 )
filler_2 = Instance.create( fulladder, 'filler_2', rowend_x0 )
filler_1.setTransformation( Transformation( toDbU(50.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
filler_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
filler_2.setTransformation( Transformation( toDbU(60.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
filler_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Filler cell placeds' )
#doBreak( 1, 'Filler cell placeds' )
#
# Getting the layers.
technology = DataBase.getDB().getTechnology()
metal2 = technology.getLayer( "METAL2" )
metal3 = technology.getLayer( "METAL3" )
via12 = technology.getLayer( "VIA12" )
via23 = technology.getLayer( "VIA23" )
# Build wiring for a.
# Create RoutingPads first.
rp1 = RoutingPad.create( a
@ -148,7 +148,7 @@ def buildFulladder ( editor ):
rp2 = RoutingPad.create( a
, Occurrence( a2_1.getPlug( a2_x2.getNet("i0")) )
, RoutingPad.BiggestArea )
# Then regular wiring.
contact1 = Contact.create( rp1, via12, toDbU( 0.0), toDbU(-15.0) )
contact2 = Contact.create( rp2, via12, toDbU( 0.0), toDbU( 10.0) )
@ -159,6 +159,7 @@ def buildFulladder ( editor ):
UpdateSession.close()
af.saveCell( fulladder, Catalog.State.Views )
Gds.save( fulladder )
return

View File

@ -79,6 +79,7 @@
hurricane/Relation.h
hurricane/RoutingPad.h hurricane/RoutingPads.h
hurricane/Diagonal.h
hurricane/Rectilinear.h
hurricane/Rubber.h hurricane/Rubbers.h
hurricane/Segment.h hurricane/Segments.h
hurricane/Selectors.h
@ -163,6 +164,7 @@
Pad.cpp
RoutingPad.cpp
Diagonal.cpp
Rectilinear.cpp
Polygon.cpp
NetExternalComponents.cpp
NetRoutingProperty.cpp

View File

@ -280,6 +280,57 @@ class Component_SlaveComponents : public Collection<Component*> {
};
// -------------------------------------------------------------------
// Class : "Component::Points_Contour".
Component::Points_Contour::Locator::Locator ( const Component* component )
: PointHL ()
, _component(component)
, _iPoint (0)
{ }
PointHL* Component::Points_Contour::Locator::getClone () const
{ return new Locator(*this); }
Point Component::Points_Contour::Locator::getElement () const
{ return _component->getPoint(_iPoint); }
bool Component::Points_Contour::Locator::isValid () const
{ return (_iPoint < _component->getPointsSize()); }
void Component::Points_Contour::Locator::progress ()
{ if (isValid()) ++_iPoint; }
string Component::Points_Contour::Locator::_getString () const
{
string s = "<" + _TName("Points_Contour::Locator")
+ getString(getElement())
+ ">";
return s;
}
PointHC* Component::Points_Contour::getClone () const
{ return new Points_Contour(*this); }
PointHL* Component::Points_Contour::getLocator () const
{ return new Locator(_component); }
string Component::Points_Contour::_getString () const
{
string s = "<" + _TName("Points_Contour") + " "
+ getString(_component)
+ ">";
return s;
}
// ****************************************************************************************************
// Component implementation
@ -463,6 +514,35 @@ void Component::_preDestroy()
cdebug_tabw(18,-1);
}
bool Component::isNonRectangle () const
{ return false; }
bool Component::isManhattanized () const
{ return false; }
size_t Component::getPointsSize () const { return 4; }
Point Component::getPoint ( size_t i ) const
{
Box bb = getBoundingBox();
switch ( i % getPointsSize() ) {
default: // To shut up gcc.
case 0: return bb.getCornerBL();
case 1: return bb.getCornerTL();
case 2: return bb.getCornerTR();
case 3: return bb.getCornerBR();
}
}
Points Component::getMContour () const
{ return getContour(); }
void Component::_toJson( JsonWriter* writer ) const
// ************************************************
{

View File

@ -78,6 +78,7 @@ namespace Hurricane {
}
bool Diagonal::isNonRectangle () const { return true; }
DbU::Unit Diagonal::getX () const { return (_target.getX() + _source.getX()) / 2; }
DbU::Unit Diagonal::getY () const { return (_target.getX() + _source.getX()) / 2; }
DbU::Unit Diagonal::getSourceX () const { return _source.getX(); }
@ -276,58 +277,6 @@ namespace Hurricane {
return record;
}
// -------------------------------------------------------------------
// Class : "Diagonal::Points_Contour".
Diagonal::Points_Contour::Locator::Locator ( const Diagonal* diagonal )
: PointHL ()
, _diagonal(diagonal)
, _iPoint (0)
{ }
PointHL* Diagonal::Points_Contour::Locator::getClone () const
{ return new Locator(*this); }
Point Diagonal::Points_Contour::Locator::getElement () const
{ return _diagonal->getPoint(_iPoint); }
bool Diagonal::Points_Contour::Locator::isValid () const
{ return (_iPoint < _diagonal->getPointsSize()); }
void Diagonal::Points_Contour::Locator::progress ()
{ if (isValid()) ++_iPoint; }
string Diagonal::Points_Contour::Locator::_getString () const
{
string s = "<" + _TName("Points_Contour::Locator")
+ getString(getElement())
+ ">";
return s;
}
PointHC* Diagonal::Points_Contour::getClone () const
{ return new Points_Contour(*this); }
PointHL* Diagonal::Points_Contour::getLocator () const
{ return new Locator(_diagonal); }
string Diagonal::Points_Contour::_getString () const
{
string s = "<" + _TName("Points_Contour") + " "
+ getString(_diagonal)
+ ">";
return s;
}
// -------------------------------------------------------------------
// Class : "JsonDiagonal".

View File

@ -232,10 +232,26 @@ namespace Hurricane {
}
bool Polygon::isNonRectangle () const
{ return true; }
bool Polygon::isManhattanized () const
{ return not _edges.empty(); }
const Layer* Polygon::getLayer () const
{ return _layer; };
size_t Polygon::getPointsSize () const
{ return _points.size(); }
Point Polygon::getPoint ( size_t i ) const
{ return _points[ i % _points.size() ]; }
DbU::Unit Polygon::getX () const
{
DbU::Unit center = 0;
@ -276,6 +292,10 @@ namespace Hurricane {
return getBoundingBox();
}
Points Polygon::getMContour () const
{ return Points_Manhattan(this); }
void Polygon::translate ( const DbU::Unit& dx, const DbU::Unit& dy )
{

View File

@ -0,0 +1,239 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
//
// This file is part of Hurricane.
//
// Hurricane is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Hurricane is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
// General Public License for more details.
//
// You should have received a copy of the Lesser GNU General Public
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
// | Authors : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Rectilinear.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Rectilinear.h"
#include "hurricane/Net.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Layer.h"
#include "hurricane/Error.h"
namespace Hurricane {
// -------------------------------------------------------------------
// Class : "Rectilinear".
Rectilinear::Rectilinear ( Net* net, const Layer* layer, const vector<Point>& points )
: Super (net)
, _layer (layer)
, _points(points)
{ }
Rectilinear* Rectilinear::create ( Net* net, const Layer* layer, const vector<Point>& points )
{
if (not layer)
throw Error( "Rectilinear::create(): Can't create, NULL layer" );
for ( size_t i=0 ; i<points.size() ; ++i ) {
size_t j = (i+1) % points.size();
if ( (points[i].getX() != points[j].getX())
and (points[i].getY() != points[j].getY()) )
throw Error( "Rectilinear::create(): Can't create, non H/V edge." );
}
Rectilinear* rectilinear = new Rectilinear ( net, layer, points );
rectilinear->_postCreate();
return rectilinear;
}
bool Rectilinear::isNonRectangle () const { return true; }
const Layer* Rectilinear::getLayer () const { return _layer; }
DbU::Unit Rectilinear::getX () const { return getBoundingBox().getCenter().getX(); }
DbU::Unit Rectilinear::getY () const { return getBoundingBox().getCenter().getY(); }
Box Rectilinear::getBoundingBox() const
{
DbU::Unit xmin = DbU::Max;
DbU::Unit ymin = DbU::Max;
DbU::Unit xmax = DbU::Min;
DbU::Unit ymax = DbU::Min;
for ( Point p : _points ) {
xmin = std::min( xmin, p.getX() );
ymin = std::min( ymin, p.getY() );
xmax = std::max( xmax, p.getX() );
ymax = std::max( ymax, p.getY() );
}
return Box( xmin, ymin, xmax, ymax );
}
Box Rectilinear::getBoundingBox ( const BasicLayer* basicLayer ) const
{
if (not _layer->contains(basicLayer)) return Box();
return getBoundingBox();
}
void Rectilinear::translate ( const DbU::Unit& dx, const DbU::Unit& dy )
{
if ( (dx != 0) or (dy != 0) ) {
invalidate( true );
for ( Point& p : _points ) p.translate( dx, dy );
}
}
void Rectilinear::setLayer ( const Layer* layer )
{
if (not layer) throw Error( "Rectilinear::setLayer(): Can't set layer, NULL layer" );
if (layer != _layer) {
invalidate( false );
_layer = layer;
}
}
void Rectilinear::setPoints ( const vector<Point>& points )
{
for ( size_t i=0 ; i<points.size() ; ++i ) {
size_t j = (i+1) % points.size();
if ( (points[i].getX() != points[j].getX())
and (points[i].getY() != points[j].getY()) )
throw Error( "Rectilinear::create(): Can't create, non H/V edge." );
}
_points = points;
invalidate(true);
}
size_t Rectilinear::getPointsSize () const
{ return _points.size(); }
Point Rectilinear::getPoint ( size_t i ) const
{
return _points[ i % getPointsSize() ];
}
void Rectilinear::_toJson ( JsonWriter* writer ) const
{
Inherit::_toJson( writer );
jsonWrite( writer, "_layer" , _layer->getName() );
}
string Rectilinear::_getTypeName () const
{ return _TName( "Rectilinear" ); }
string Rectilinear::_getString () const
{
string s = Super::_getString();
s.insert( s.length() - 1, " " + getString(_layer->getName()) );
s.insert( s.length() - 1, " points:" + getString(_points.size()) );
return s;
}
Record* Rectilinear::_getRecord () const
{
Record* record = Super::_getRecord();
if (record) {
record->add( getSlot("_layer" , _layer ) );
record->add( getSlot("_points", &_points) );
}
return record;
}
// -------------------------------------------------------------------
// Class : "JsonRectilinear".
Initializer<JsonRectilinear> jsonRectilinearInit ( 0 );
void JsonRectilinear::initialize ()
{ JsonTypes::registerType( new JsonRectilinear (JsonWriter::RegisterMode) ); }
JsonRectilinear::JsonRectilinear ( unsigned long flags )
: JsonComponent(flags)
{
add( "_layer" , typeid(string) );
}
string JsonRectilinear::getTypeName () const
{ return "Rectilinear"; }
JsonRectilinear* JsonRectilinear::clone ( unsigned long flags ) const
{ return new JsonRectilinear ( flags ); }
void JsonRectilinear::toData ( JsonStack& stack )
{
check( stack, "JsonRectilinear::toData" );
unsigned int jsonId = presetId( stack );
vector<Point> points;
// Have to loop over all the points.
//points.push_back( get<Point>(stack,".Point") );
Rectilinear* rectilinear = Rectilinear::create
( get<Net*>(stack,".Net")
, DataBase::getDB()->getTechnology()->getLayer( get<const char*>(stack,"_layer") )
, points
);
JsonNet* jnet = jget<JsonNet>( stack );
if (jnet) {
jnet->addHookLink( rectilinear->getBodyHook (), jsonId, get<string>(stack,"_bodyHook" ) );
} else {
cerr << Error( "Jsonrectilinear::toData(): Missing (Json)Net in stack context." ) << endl;
}
// Hook/Ring rebuild are done as a post-process.
update( stack, rectilinear );
}
} // Hurricane namespace.

View File

@ -70,6 +70,10 @@ class Box {
public: DbU::Unit getXCenter() const {return ((_xMin + _xMax) / 2);};
public: DbU::Unit getYCenter() const {return ((_yMin + _yMax) / 2);};
public: Point getCenter() const {return Point(getXCenter(), getYCenter());};
public: Point getCornerBL() const { return Point(_xMin,_yMin); }
public: Point getCornerTL() const { return Point(_xMin,_yMax); }
public: Point getCornerTR() const { return Point(_xMax,_yMax); }
public: Point getCornerBR() const { return Point(_xMax,_yMin); }
public: DbU::Unit getWidth() const {return (_xMax - _xMin);};
public: DbU::Unit getHalfWidth() const {return (getWidth() / 2);};

View File

@ -17,136 +17,167 @@
// not, see <http://www.gnu.org/licenses/>.
// ****************************************************************************************************
#ifndef HURRICANE_COMPONENT
#define HURRICANE_COMPONENT
#ifndef HURRICANE_COMPONENT_H
#define HURRICANE_COMPONENT_H
#include "hurricane/Points.h"
#include "hurricane/Go.h"
#include "hurricane/Components.h"
#include "hurricane/Hook.h"
#include "hurricane/Hooks.h"
#include "hurricane/Interval.h"
namespace Hurricane {
class Net;
class Rubber;
class Layer;
class Net;
class Rubber;
class Layer;
// ****************************************************************************************************
// Component declaration
// ****************************************************************************************************
// -------------------------------------------------------------------
// Class : "Component".
class Component : public Go {
// ************************
class Component : public Go {
public:
typedef Go Inherit;
// Types
// *****
public:
class Points_Contour : public PointHC {
public:
class Locator : public PointHL {
public:
Locator ( const Component* );
inline Locator ( const Locator& );
virtual Point getElement () const;
virtual PointHL* getClone () const;
virtual bool isValid () const;
virtual void progress ();
virtual string _getString () const;
protected:
const Component* _component;
size_t _iPoint;
};
public:
inline Points_Contour ( const Component* );
inline Points_Contour ( const Points_Contour& );
virtual PointHC* getClone () const;
virtual PointHL* getLocator () const;
virtual string _getString () const;
protected:
const Component* _component;
};
public: typedef Go Inherit;
public:
class BodyHook : public Hook {
friend class Component;
public:
typedef Hook Inherit;
public:
virtual Component* getComponent () const;
virtual bool isMaster () const {return true;};
virtual string _getTypeName () const { return "Component::BodyHook"; };
virtual string _getString () const;
static Hook* _compToHook ( Component* );
private:
BodyHook ( Component* );
};
public: class BodyHook : public Hook {
// *********************************
friend class Component;
public: typedef Hook Inherit;
private: BodyHook(Component* component);
public: virtual Component* getComponent() const;
public: virtual bool isMaster() const {return true;};
public: virtual string _getTypeName() const { return "Component::BodyHook"; };
public: virtual string _getString() const;
public: static Hook* _compToHook(Component*);
};
// Attributes
// **********
private: Net* _net;
private: Rubber* _rubber;
private: BodyHook _bodyHook;
private: Component* _nextOfNetComponentSet;
// Constructors
// ************
protected: Component(Net* net, bool inPlugCreate = false);
// Accessors
// *********
public: virtual Cell* getCell() const;
public: Net* getNet() const {return _net;};
public: Rubber* getRubber() const {return _rubber;};
public: Hook* getBodyHook() {return &_bodyHook;};
public: virtual Hooks getHooks() const;
public: virtual DbU::Unit getX() const = 0;
public: virtual DbU::Unit getY() const = 0;
public: virtual Point getPosition() const {return Point(getX(), getY());};
public: virtual Point getCenter() const {return getPosition();};
public: virtual const Layer* getLayer() const = 0;
public: virtual Box getBoundingBox() const = 0;
public: virtual Box getBoundingBox(const BasicLayer* basicLayer) const = 0;
public: Components getConnexComponents() const;
public: Components getSlaveComponents() const;
// Updators
// ********
public: virtual void materialize();
public: virtual void unmaterialize();
public: virtual void invalidate(bool propagateFlag = true);
public: virtual void forceId(unsigned int id);
// Filters
// *******
public: static ComponentFilter getIsUnderFilter(const Box& area);
// Others
// ******
protected: virtual void _postCreate();
protected: virtual void _preDestroy();
public: virtual void _toJson ( JsonWriter* ) const;
public: virtual void _toJsonSignature(JsonWriter*) const;
public: virtual string _getString() const;
public: virtual Record* _getRecord() const;
public: Component* _getNextOfNetComponentSet() const {return _nextOfNetComponentSet;};
public: void _setNet(Net* net);
public: void _setRubber(Rubber* rubber);
public: void _setNextOfNetComponentSet(Component* component) {_nextOfNetComponentSet = component;};
};
protected:
Component ( Net* , bool inPlugCreate = false );
public:
// Accessors.
virtual bool isManhattanized () const;
virtual bool isNonRectangle () const;
virtual Cell* getCell () const;
Net* getNet () const { return _net; };
Rubber* getRubber () const { return _rubber; };
Hook* getBodyHook () { return &_bodyHook; };
virtual Hooks getHooks () const;
virtual DbU::Unit getX () const = 0;
virtual DbU::Unit getY () const = 0;
virtual Point getPosition () const { return Point( getX(), getY() ); };
virtual Point getCenter () const { return getPosition(); };
virtual const Layer* getLayer () const = 0;
virtual size_t getPointsSize () const;
virtual Point getPoint ( size_t ) const;
virtual Box getBoundingBox () const = 0;
virtual Box getBoundingBox ( const BasicLayer* ) const = 0;
inline Points getContour () const;
virtual Points getMContour () const;
Components getConnexComponents () const;
Components getSlaveComponents () const;
// Mutators.
virtual void materialize ();
virtual void unmaterialize ();
virtual void invalidate ( bool propagateFlag = true );
virtual void forceId ( unsigned int id );
// Filters
static ComponentFilter getIsUnderFilter ( const Box& area );
// Others
protected:
virtual void _postCreate ();
virtual void _preDestroy ();
public:
virtual void _toJson ( JsonWriter* ) const;
virtual void _toJsonSignature ( JsonWriter* ) const;
virtual string _getString () const;
virtual Record* _getRecord () const;
Component* _getNextOfNetComponentSet () const {return _nextOfNetComponentSet;};
void _setNet ( Net* );
void _setRubber ( Rubber* );
void _setNextOfNetComponentSet ( Component* component ) { _nextOfNetComponentSet = component; };
private:
Net* _net;
Rubber* _rubber;
BodyHook _bodyHook;
Component* _nextOfNetComponentSet;
};
double getArea ( Component* component );
inline Points Component::getContour () const { return Points_Contour(this); }
inline Component::Points_Contour::Locator::Locator ( const Locator &locator )
: PointHL ()
, _component(locator._component)
, _iPoint (locator._iPoint)
{ }
class JsonComponent : public JsonEntity {
// ************************************
public: JsonComponent(unsigned long flags);
};
inline Component::Points_Contour::Points_Contour ( const Component* component )
: PointHC ()
, _component(component)
{ }
} // End of Hurricane namespace.
inline Component::Points_Contour::Points_Contour ( const Points_Contour& other )
: PointHC ()
, _component(other._component)
{ }
double getArea ( Component* component );
// -------------------------------------------------------------------
// Class : "JsonComponent".
class JsonComponent : public JsonEntity {
public:
JsonComponent ( unsigned long flags );
};
} // Hurricane namespace.
INSPECTOR_P_SUPPORT(Hurricane::Component);
INSPECTOR_P_SUPPORT(Hurricane::Component::BodyHook);
#endif // HURRICANE_COMPONENT
#endif // HURRICANE_COMPONENT_H
// ****************************************************************************************************
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved

View File

@ -32,7 +32,6 @@
#ifndef HURRICANE_DIAGONAL_H
#define HURRICANE_DIAGONAL_H
#include "hurricane/Points.h"
#include "hurricane/Component.h"
@ -47,36 +46,11 @@ namespace Hurricane {
class Diagonal : public Component {
public:
typedef Component Super;
public:
class Points_Contour : public PointHC {
public:
class Locator : public PointHL {
public:
Locator ( const Diagonal* );
inline Locator ( const Locator& );
virtual Point getElement () const;
virtual PointHL* getClone () const;
virtual bool isValid () const;
virtual void progress ();
virtual string _getString () const;
protected:
const Diagonal* _diagonal;
size_t _iPoint;
};
public:
inline Points_Contour ( const Diagonal* );
inline Points_Contour ( const Points_Contour& );
virtual PointHC* getClone () const;
virtual PointHL* getLocator () const;
virtual string _getString () const;
protected:
const Diagonal* _diagonal;
};
public:
static Diagonal* create ( Net*, const Layer*, const Point& source, const Point& target, DbU::Unit width );
// Accessors.
virtual bool isNonRectangle () const;
virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const;
virtual DbU::Unit getSourceX () const;
@ -87,11 +61,10 @@ namespace Hurricane {
virtual Point getTargetPosition () const;
virtual Box getBoundingBox () const;
virtual Box getBoundingBox ( const BasicLayer* ) const;
size_t getPointsSize () const;
Point getPoint ( size_t i ) const;
virtual size_t getPointsSize () const;
virtual Point getPoint ( size_t i ) const;
DbU::Unit getWidth () const;
virtual const Layer* getLayer () const;
inline Points getContour () const;
// Mutators.
void setLayer ( const Layer* );
void setWidth ( DbU::Unit );
@ -116,28 +89,6 @@ namespace Hurricane {
};
inline Points Diagonal::getContour () const { return Points_Contour(this); }
inline Diagonal::Points_Contour::Locator::Locator ( const Locator &locator )
: PointHL ()
, _diagonal(locator._diagonal)
, _iPoint (locator._iPoint)
{ }
inline Diagonal::Points_Contour::Points_Contour ( const Diagonal* diagonal )
: PointHC ()
, _diagonal(diagonal)
{ }
inline Diagonal::Points_Contour::Points_Contour ( const Points_Contour& other )
: PointHC ()
, _diagonal(other._diagonal)
{ }
// -------------------------------------------------------------------
// Class : "JsonRoutingDiagonal".

View File

@ -32,7 +32,6 @@
#ifndef HURRICANE_POLYGON_H
#define HURRICANE_POLYGON_H
#include "hurricane/Points.h"
#include "hurricane/Component.h"
#include "hurricane/Polygons.h"
@ -109,12 +108,14 @@ namespace Hurricane {
static Polygon* create ( Net*, const Layer*, const std::vector<Point>& );
static float getSlope ( const Point&, const Point& );
public:
inline bool isManhattanized () const;
virtual bool isNonRectangle () const;
virtual bool isManhattanized () const;
virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const;
inline const vector<Point>& getPoints () const;
inline const vector<Edge*>& getEdges () const;
inline const Point& getPoint ( size_t ) const;
virtual size_t getPointsSize () const;
virtual Point getPoint ( size_t ) const;
virtual Box getBoundingBox () const;
virtual Box getBoundingBox ( const BasicLayer* ) const;
virtual const Layer* getLayer () const;
@ -124,7 +125,7 @@ namespace Hurricane {
static float getSign ( const vector<Point>&, size_t );
float getSlope ( size_t i ) const;
void manhattanize ();
inline Points getContour () const;
virtual Points getMContour () const;
virtual void _toJson ( JsonWriter* ) const;
static JsonObject* getJsonObject ( unsigned long flags );
virtual string _getTypeName () const;
@ -140,11 +141,8 @@ namespace Hurricane {
};
inline bool Polygon::isManhattanized () const { return not _edges.empty(); }
inline const vector<Polygon::Edge*>& Polygon::getEdges () const { return _edges; }
inline const vector<Point>& Polygon::getPoints () const { return _points; }
inline const Point& Polygon::getPoint ( size_t i ) const { return _points[ (i<_points.size()) ? i : 0 ]; }
inline Points Polygon::getContour () const { return Points_Manhattan(this); }
inline bool Polygon::Edge::isClockwise () const { return (_flags & Polygon::Clockwise); }
inline bool Polygon::Edge::isYIncrease () const { return (_flags & Polygon::YIncrease); }

View File

@ -0,0 +1,98 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
//
// This file is part of Hurricane.
//
// Hurricane is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// Hurricane is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-
// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
// General Public License for more details.
//
// You should have received a copy of the Lesser GNU General Public
// License along with Hurricane. If not, see
// <http://www.gnu.org/licenses/>.
//
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
// | V L S I B a c k e n d D a t a - B a s e |
// | |
// | Authors : Jean-Paul Chaput |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/Rectilinear.h" |
// +-----------------------------------------------------------------+
#ifndef HURRICANE_RECTILINEAR_H
#define HURRICANE_RECTILINEAR_H
#include "hurricane/Component.h"
namespace Hurricane {
class Layer;
// -------------------------------------------------------------------
// Class : "Rectilinear".
class Rectilinear : public Component {
public:
typedef Component Super;
public:
static Rectilinear* create ( Net*, const Layer*, const vector<Point>& );
// Accessors.
virtual bool isNonRectangle () const;
virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const;
virtual Box getBoundingBox () const;
virtual Box getBoundingBox ( const BasicLayer* ) const;
virtual size_t getPointsSize () const;
virtual Point getPoint ( size_t i ) const;
virtual const Layer* getLayer () const;
inline Points getContour () const;
// Mutators.
void setLayer ( const Layer* );
virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy );
void setPoints ( const vector<Point>& );
// Hurricane management.
virtual void _toJson ( JsonWriter* ) const;
static JsonObject* getJsonObject ( unsigned long flags );
virtual string _getTypeName () const;
virtual string _getString () const;
virtual Record* _getRecord () const;
protected:
Rectilinear ( Net*, const Layer*, const vector<Point>& );
private:
const Layer* _layer;
vector<Point> _points;
};
// -------------------------------------------------------------------
// Class : "JsonRoutingRectilinear".
class JsonRectilinear : public JsonComponent {
public:
static void initialize ();
JsonRectilinear ( unsigned long flags );
virtual std::string getTypeName () const;
virtual JsonRectilinear* clone ( unsigned long ) const;
virtual void toData ( JsonStack& );
};
} // Hurricane namespace.
INSPECTOR_P_SUPPORT(Hurricane::Rectilinear);
#endif // HURRICANE_RECTILINEAR_H

View File

@ -67,6 +67,7 @@
PySegmentCollection.cpp
PyTechnology.cpp
PyTransformation.cpp
PyRectilinear.cpp
PyPolygon.cpp
PyOrientation.cpp
PyDbU.cpp
@ -135,6 +136,7 @@
hurricane/isobar/PySegmentCollection.h
hurricane/isobar/PyTechnology.h
hurricane/isobar/PyTransformation.h
hurricane/isobar/PyRectilinear.h
hurricane/isobar/PyPolygon.h
hurricane/isobar/PyOrientation.h
hurricane/isobar/PyDbU.h

View File

@ -73,6 +73,7 @@
#include "hurricane/isobar/PyVertical.h"
#include "hurricane/isobar/PyPad.h"
#include "hurricane/isobar/PyDiagonal.h"
#include "hurricane/isobar/PyRectilinear.h"
#include "hurricane/isobar/PyPolygon.h"
#include "hurricane/isobar/PyPath.h"
#include "hurricane/isobar/PyOccurrence.h"
@ -572,7 +573,7 @@ extern "C" {
PyHorizontal_LinkPyType ();
PyContact_LinkPyType ();
PyPin_LinkPyType ();
PyPolygon_LinkPyType ();
PyRectilinear_LinkPyType ();
PyPlug_LinkPyType ();
PyPolygon_LinkPyType ();
PyBreakpoint_LinkPyType ();
@ -658,6 +659,7 @@ extern "C" {
PYTYPE_READY_SUB ( Plug , Component)
PYTYPE_READY_SUB ( Pad , Component)
PYTYPE_READY_SUB ( Diagonal , Component)
PYTYPE_READY_SUB ( Rectilinear , Component)
PYTYPE_READY_SUB ( Polygon , Component)
// Identifier string can take up to 10 characters !
@ -711,6 +713,7 @@ extern "C" {
__cs.addType ( "segment" , &PyTypeSegment , "<Segment>" , false, "comp" );
__cs.addType ( "pad " , &PyTypePad , "<Pad>" , false, "comp" );
__cs.addType ( "diagonal" , &PyTypeDiagonal , "<Diagonal>" , false, "comp" );
__cs.addType ( "rectilin" , &PyTypeRectilinear , "<Rectilinear>" , false, "comp" );
__cs.addType ( "polygon" , &PyTypePolygon , "<Polygon>" , false, "comp" );
__cs.addType ( "segmentCol" , &PyTypeSegmentCollection , "<SegmentCollection>" , false );
__cs.addType ( "db" , &PyTypeDataBase , "<DataBase>" , false );
@ -812,6 +815,8 @@ extern "C" {
PyModule_AddObject ( module, "Pad" , (PyObject*)&PyTypePad );
Py_INCREF ( &PyTypeDiagonal );
PyModule_AddObject ( module, "Diagonal" , (PyObject*)&PyTypeDiagonal );
Py_INCREF ( &PyTypeRectilinear );
PyModule_AddObject ( module, "Rectilinear" , (PyObject*)&PyTypeRectilinear );
Py_INCREF ( &PyTypePolygon );
PyModule_AddObject ( module, "Polygon" , (PyObject*)&PyTypePolygon );

View File

@ -0,0 +1,209 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyRectilinear.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyPoint.h"
#include "hurricane/isobar/PyNet.h"
#include "hurricane/isobar/PyLayer.h"
#include "hurricane/isobar/PyBox.h"
#include "hurricane/isobar/PyRectilinear.h"
namespace Isobar {
using namespace Hurricane;
template< typename CppType >
bool ListToVector ( PyObject* list, PyTypeObject* itemType, std::vector<CppType>& v )
{
if (not PyList_Check(list)) return false;
int length = PyList_Size( list );
for ( int i=0 ; i<length ; ++i ) {
PyObject* item = PyList_GetItem( list, i );
if ((item)->ob_type != itemType) {
string message = "Rectilinear: Item at position " + getString(i) + "has wrong type.";
PyErr_SetString( ConstructorError, message.c_str() );
return false;
}
v.push_back( *PYPOINT_O(item) );
}
return true;
}
extern "C" {
#undef ACCESS_OBJECT
#undef ACCESS_CLASS
#define ACCESS_OBJECT _baseObject._baseObject._object
#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Rectilinear,rectilinear,function)
// +=================================================================+
// | "PyRectilinear" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// Standard Accessors (Attributes).
DirectGetLongAttribute(PyRectilinear_getX, getX, PyRectilinear, Rectilinear)
DirectGetLongAttribute(PyRectilinear_getY, getY, PyRectilinear, Rectilinear)
// Standard Destroy (Attribute).
DBoDestroyAttribute(PyRectilinear_destroy, PyRectilinear)
static PyObject* PyRectilinear_create ( PyObject*, PyObject *args )
{
cdebug_log(20,0) << "PyRectilinear_create()" << endl;
PyObject* arg0 = NULL;
PyObject* arg1 = NULL;
PyObject* arg2 = NULL;
Rectilinear* rectilinear = NULL;
HTRY
if (not PyArg_ParseTuple(args, "OOO:Rectilinear.create" ,&arg0 ,&arg1 ,&arg2 )) {
PyErr_SetString( ConstructorError, "Invalid number of parameters for Rectilinear constructor." );
return NULL;
}
if (not IsPyNet(arg0)) {
PyErr_SetString( ConstructorError, "First parameter of Rectilinear constructor must be a Net." );
return NULL;
}
if (not IsPyDerivedLayer(arg1)) {
PyErr_SetString( ConstructorError, "Second parameter of Rectilinear constructor must be a Layer." );
return NULL;
}
vector<Point> points;
if (not ListToVector<Point>(arg2,&PyTypePoint,points)) return NULL;
rectilinear = Rectilinear::create( PYNET_O(arg0), PYDERIVEDLAYER_O(arg1), points );
HCATCH
return PyRectilinear_Link(rectilinear);
}
static PyObject* PyRectilinear_getBoundingBox ( PyRectilinear *self )
{
cdebug_log(20,0) << "PyRectilinear_getBoundingBox()" << endl;
METHOD_HEAD( "Rectilinear.BoundingBox()" )
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
if (pyBox == NULL) { return NULL; }
HTRY
pyBox->_object = new Box ( rectilinear->getBoundingBox() );
HCATCH
return (PyObject*)pyBox;
}
static PyObject* PyRectilinear_setPoints ( PyRectilinear *self, PyObject* args )
{
cdebug_log(20,0) << "Rectilinear.setPoints()" << endl;
HTRY
METHOD_HEAD( "Rectilinear.setPoints()" )
PyObject* arg0 = NULL;
PyObject* arg1 = NULL;
PyObject* arg2 = NULL;
if (not PyArg_ParseTuple( args, "O:Rectilinear.setPoints", &arg0 )) {
PyErr_SetString( ConstructorError, "Invalid number of parameters for Rectilinear.setPoints()." );
return NULL;
}
vector<Point> points;
if (not ListToVector<Point>(arg0,&PyTypePoint,points)) return NULL;
rectilinear->setPoints( points );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyRectilinear_translate ( PyRectilinear *self, PyObject* args )
{
cdebug_log(20,0) << "PyRectilinear_translate ()" << endl;
HTRY
METHOD_HEAD ( "Rectilinear.translate()" )
PyObject* arg0 = NULL;
PyObject* arg1 = NULL;
__cs.init ("Rectilinear.translate");
if (PyArg_ParseTuple(args,"O&O&:Rectilinear.translate", Converter, &arg0, Converter, &arg1)) {
if (__cs.getObjectIds() == INTS2_ARG) rectilinear->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) );
else {
PyErr_SetString ( ConstructorError, "Rectilinear.translate(): Invalid type for parameter(s)." );
return NULL;
}
} else {
PyErr_SetString ( ConstructorError, "Rectilinear.translate(): Invalid number of parameters." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
// ---------------------------------------------------------------
// PyRectilinear Attribute Method table.
PyMethodDef PyRectilinear_Methods[] =
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
, "Create a new Rectilinear polygon." }
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }
, { "setPoints" , (PyCFunction)PyRectilinear_setPoints , METH_VARARGS, "Sets the Rectilinear Bounding Box." }
, { "translate" , (PyCFunction)PyRectilinear_translate , METH_VARARGS, "Translates the Rectilinear of dx and dy." }
, { "destroy" , (PyCFunction)PyRectilinear_destroy , METH_NOARGS
, "Destroy associated hurricane object, the python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
DBoDeleteMethod(Rectilinear)
PyTypeObjectLinkPyType(Rectilinear)
#else // Python Module Code Part.
// +=================================================================+
// | "PyRectilinear" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
DBoLinkCreateMethod(Rectilinear)
PyTypeInheritedObjectDefinitions(Rectilinear,Component)
#endif // Shared Library Code Part.
} // extern "C".
} // Isobar namespace.

View File

@ -0,0 +1,56 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/isobar/PyRectilinear.h" |
// +-----------------------------------------------------------------+
#ifndef PY_RECTILINEAR_H
#define PY_RECTILINEAR_H
#include "hurricane/isobar/PyComponent.h"
#include "hurricane/Rectilinear.h"
namespace Isobar {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyRectilinear".
typedef struct {
PyComponent _baseObject;
} PyRectilinear;
// -------------------------------------------------------------------
// Functions & Types exported to "PyHurricane.ccp".
extern PyTypeObject PyTypeRectilinear;
extern PyMethodDef PyRectilinear_Methods[];
extern PyObject* PyRectilinear_Link ( Hurricane::Rectilinear* object );
extern void PyRectilinear_LinkPyType ();
#define IsPyRectilinear(v) ( (v)->ob_type == &PyTypeRectilinear )
#define PYRECTILINEAR(v) ( (PyRectilinear*)(v) )
#define PYRECTILINEAR_O(v) ( PYRECTILINEAR(v)->_baseObject._baseObject._object )
} // extern "C".
} // Isobar namespace.
#endif // PY_RECTILINEAR_H

View File

@ -40,6 +40,7 @@
#include "hurricane/Contact.h"
#include "hurricane/Pad.h"
#include "hurricane/Diagonal.h"
#include "hurricane/Rectilinear.h"
#include "hurricane/Polygon.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/ExtensionGo.h"
@ -666,47 +667,30 @@ namespace Hurricane {
static QRect rectangle;
static unsigned int state;
const Diagonal* diagonal = dynamic_cast<const Diagonal*>(go);
if (diagonal) {
_goCount++;
Box bb = transformation.getBox(diagonal->getBoundingBox(basicLayer));
rectangle = _cellWidget->dbuToScreenRect( bb );
if ( (rectangle.width() > 4) and (rectangle.height() > 4) ) {
QPolygon contour;
for ( Point point : diagonal->getContour() )
contour << _cellWidget->dbuToScreenPoint( point );
_cellWidget->drawScreenPolygon( contour );
}
return;
}
const Polygon* polygon = dynamic_cast<const Polygon*>(go);
if (polygon) {
_goCount++;
Box bb = transformation.getBox(polygon->getBoundingBox(basicLayer));
rectangle = _cellWidget->dbuToScreenRect( bb );
if ( (rectangle.width() > 4) and (rectangle.height() > 4) ) {
QPolygon contour;
const vector<Point>& points = polygon->getPoints();
for ( Point point : points ) contour << _cellWidget->dbuToScreenPoint( point );
_cellWidget->drawScreenPolygon( contour );
contour.clear();
if (_cellWidget->dbuToScreenLength(DbU::getPolygonStep()) > 4) {
for ( Point point : polygon->getContour() )
contour << _cellWidget->dbuToScreenPoint( point );
_cellWidget->drawScreenPolygon( contour );
}
}
return;
}
const Component* component = dynamic_cast<const Component*>(go);
if (component) {
_goCount++;
Box bb = transformation.getBox(component->getBoundingBox(basicLayer));
rectangle = _cellWidget->dbuToScreenRect( bb );
state = ( (rectangle.width() > 2) ? 1:0) | ( (rectangle.height() > 2) ? 2:0);
if (component->isNonRectangle()) {
if ( (rectangle.width() > 4) and (rectangle.height() > 4) ) {
QPolygon contour;
for ( Point point : component->getContour() )
contour << _cellWidget->dbuToScreenPoint( point );
_cellWidget->drawScreenPolygon( contour );
if ( component->isManhattanized()
and (_cellWidget->dbuToScreenLength(DbU::getPolygonStep()) > 4) ) {
for ( Point point : component->getMContour() )
contour << _cellWidget->dbuToScreenPoint( point );
_cellWidget->drawScreenPolygon( contour );
}
}
return;
}
state = ( (rectangle.width() > 2) ? 1:0) | ( (rectangle.height() > 2) ? 2:0);
switch ( state ) {
case 0: break;
case 1: _cellWidget->drawScreenLine( rectangle.bottomLeft(), rectangle.bottomRight() ); break;