From ea16b5a55608883c6a9fc76e0d4c0a1d2705ace4 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sun, 20 May 2018 15:47:34 +0200 Subject: [PATCH] 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. --- crlcore/etc/45/freepdk_45/technology.conf | 102 +- crlcore/src/ccore/CMakeLists.txt | 1 + crlcore/src/ccore/crlcore/Gds.h | 3 + crlcore/src/ccore/gds/GdsParser.cpp | 1109 +++++++++++++++++ crlcore/src/pyCRL/CMakeLists.txt | 2 + crlcore/src/pyCRL/PyCRL.cpp | 5 + crlcore/src/pyCRL/PyGds.cpp | 144 +++ crlcore/src/pyCRL/crlcore/PyGds.h | 55 + documentation/examples/scripts/diagonals.py | 3 +- documentation/examples/scripts/fulladder.py | 39 +- hurricane/src/hurricane/CMakeLists.txt | 2 + hurricane/src/hurricane/Component.cpp | 80 ++ hurricane/src/hurricane/Diagonal.cpp | 53 +- hurricane/src/hurricane/Polygon.cpp | 20 + hurricane/src/hurricane/Rectilinear.cpp | 239 ++++ hurricane/src/hurricane/hurricane/Box.h | 4 + hurricane/src/hurricane/hurricane/Component.h | 237 ++-- hurricane/src/hurricane/hurricane/Diagonal.h | 55 +- hurricane/src/hurricane/hurricane/Polygon.h | 12 +- .../src/hurricane/hurricane/Rectilinear.h | 98 ++ hurricane/src/isobar/CMakeLists.txt | 2 + hurricane/src/isobar/PyHurricane.cpp | 7 +- hurricane/src/isobar/PyRectilinear.cpp | 209 ++++ .../isobar/hurricane/isobar/PyRectilinear.h | 56 + hurricane/src/viewer/CellWidget.cpp | 56 +- 25 files changed, 2280 insertions(+), 313 deletions(-) create mode 100644 crlcore/src/ccore/gds/GdsParser.cpp create mode 100644 crlcore/src/pyCRL/PyGds.cpp create mode 100644 crlcore/src/pyCRL/crlcore/PyGds.h create mode 100644 hurricane/src/hurricane/Rectilinear.cpp create mode 100644 hurricane/src/hurricane/hurricane/Rectilinear.h create mode 100644 hurricane/src/isobar/PyRectilinear.cpp create mode 100644 hurricane/src/isobar/hurricane/isobar/PyRectilinear.h diff --git a/crlcore/etc/45/freepdk_45/technology.conf b/crlcore/etc/45/freepdk_45/technology.conf index e9487027..bc537d9f 100644 --- a/crlcore/etc/45/freepdk_45/technology.conf +++ b/crlcore/etc/45/freepdk_45/technology.conf @@ -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) ) diff --git a/crlcore/src/ccore/CMakeLists.txt b/crlcore/src/ccore/CMakeLists.txt index 9db9d78e..3ed2f839 100644 --- a/crlcore/src/ccore/CMakeLists.txt +++ b/crlcore/src/ccore/CMakeLists.txt @@ -117,6 +117,7 @@ alliance/ap/ApDriver.cpp ) set ( gds_cpps gds/GdsDriver.cpp + gds/GdsParser.cpp ) set ( cif_cpps cif/CifDriver.cpp ) diff --git a/crlcore/src/ccore/crlcore/Gds.h b/crlcore/src/ccore/crlcore/Gds.h index 107c758d..d4401841 100644 --- a/crlcore/src/ccore/crlcore/Gds.h +++ b/crlcore/src/ccore/crlcore/Gds.h @@ -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 ); }; diff --git a/crlcore/src/ccore/gds/GdsParser.cpp b/crlcore/src/ccore/gds/GdsParser.cpp new file mode 100644 index 00000000..e3f889bc --- /dev/null +++ b/crlcore/src/ccore/gds/GdsParser.cpp @@ -0,0 +1,1109 @@ +// -*- 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 | +// | G D S I I / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./gds/GdsParser.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include "vlsisapd/configuration/Configuration.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Diagonal.h" +#include "hurricane/Rectilinear.h" +#include "hurricane/Pad.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Library.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/UpdateSession.h" +using namespace Hurricane; + +#include "crlcore/Utilities.h" +#include "crlcore/NetExtension.h" +#include "crlcore/ToolBox.h" +#include "crlcore/Gds.h" +using namespace CRL; + + +namespace { + + +// ------------------------------------------------------------------- +// Class : "::GdsRecord". + + class GdsRecord { + public: + // Data Types. + static const uint16_t NoData = 0x0000; + static const uint16_t BitArray = 0x0001; + static const uint16_t TwoByteInteger = 0x0002; // Signed, 16 bits. + static const uint16_t FourByteInteger = 0x0003; // Signed, 32 bits. + static const uint16_t FourByteReal = 0x0004; // Unused. + static const uint16_t EightByteReal = 0x0005; + static const uint16_t String = 0x0006; + // Record Types. + static const uint16_t HEADER = 0x0000 | TwoByteInteger; + static const uint16_t BGNLIB = 0x0100 | TwoByteInteger; + static const uint16_t LIBNAME = 0x0200 | String; + static const uint16_t UNITS = 0x0300 | EightByteReal; + static const uint16_t ENDLIB = 0x0400 | NoData; + static const uint16_t BGNSTR = 0x0500 | TwoByteInteger; + static const uint16_t STRNAME = 0x0600 | String; + static const uint16_t ENDSTR = 0x0700 | NoData; + static const uint16_t BOUNDARY = 0x0800 | NoData; + static const uint16_t PATH = 0x0900 | NoData; + static const uint16_t SREF = 0x0a00 | NoData; + static const uint16_t AREF = 0x0b00 | NoData; + static const uint16_t TEXT = 0x0c00 | NoData; + static const uint16_t LAYER = 0x0d00 | TwoByteInteger; + static const uint16_t DATATYPE = 0x0e00 | TwoByteInteger; + static const uint16_t WIDTH = 0x0f00 | FourByteInteger; + static const uint16_t XY = 0x1000 | FourByteInteger; + static const uint16_t ENDEL = 0x1100 | NoData; + static const uint16_t SNAME = 0x1200 | String; + static const uint16_t COLROW = 0x1300 | TwoByteInteger; + static const uint16_t TEXTNODE = 0x1400 | NoData; // Unused. + static const uint16_t NODE = 0x1500 | NoData; + static const uint16_t TEXTTYPE = 0x1600 | TwoByteInteger; + static const uint16_t PRESENTATION = 0x1700 | BitArray; + static const uint16_t SPACING = 0x1800 | NoData; // Discontinued. + static const uint16_t STRING = 0x1900 | String; + static const uint16_t STRANS = 0x1a00 | BitArray; + static const uint16_t MAG = 0x1b00 | EightByteReal; + static const uint16_t ANGLE = 0x1c00 | EightByteReal; + static const uint16_t REFLIBS = 0x1f00 | String; + static const uint16_t FONTS = 0x2000 | String; + static const uint16_t PATHTYPE = 0x2100 | TwoByteInteger; + static const uint16_t GENERATIONS = 0x2200 | TwoByteInteger; + static const uint16_t ATTRTABLE = 0x2300 | String; + static const uint16_t STYPTABLE = 0x2400 | String; // Unreleased. + static const uint16_t STRTYPE = 0x2500 | TwoByteInteger; // Unreleased. + static const uint16_t ELFLAGS = 0x2600 | BitArray; + static const uint16_t ELKEY = 0x2700 | FourByteInteger; // Unreleased. + static const uint16_t LINKTYPE = 0x2800 | TwoByteInteger; // Unreleased. + static const uint16_t LINKKEYS = 0x2900 | FourByteInteger; // Unreleased. + static const uint16_t NODETYPE = 0x2a00 | TwoByteInteger; + static const uint16_t PROPATTR = 0x2b00 | TwoByteInteger; + static const uint16_t PROPVALUE = 0x2c00 | String; + static const uint16_t BOX = 0x2d00 | NoData; + static const uint16_t BOXTYPE = 0x2e00 | TwoByteInteger; + static const uint16_t PLEX = 0x2f00 | FourByteInteger; + static const uint16_t BGNEXTN = 0x3000 | FourByteInteger; // CustomPlus. + static const uint16_t ENDEXTN = 0x3100 | FourByteInteger; // CustomPlus. + static const uint16_t TAPENUM = 0x3200 | TwoByteInteger; + static const uint16_t TAPECODE = 0x3300 | TwoByteInteger; + static const uint16_t STRCLASS = 0x3400 | BitArray; // CustomPlus. + static const uint16_t RESERVED = 0x3500 | FourByteInteger; // Future use. + static const uint16_t FORMAT = 0x3600 | TwoByteInteger; + static const uint16_t MASK = 0x3700 | String; // Filtered format. + static const uint16_t ENDMASKS = 0x3800 | NoData; // Filtered format. + static const uint16_t LIBDIRSIZE = 0x3900 | TwoByteInteger; + static const uint16_t SRFNAME = 0x3a00 | String; + static const uint16_t LIBSECUR = 0x3b00 | TwoByteInteger; + public: + GdsRecord (); + inline bool isHEADER () const; + inline bool isBGNLIB () const; + inline bool isLIBNAME () const; + inline bool isUNITS () const; + inline bool isENDLIB () const; + inline bool isBGNSTR () const; + inline bool isSTRNAME () const; + inline bool isENDSTR () const; + inline bool isBOUNDARY () const; + inline bool isPATH () const; + inline bool isSREF () const; + inline bool isAREF () const; + inline bool isTEXT () const; + inline bool isLAYER () const; + inline bool isDATATYPE () const; + inline bool isWIDTH () const; + inline bool isXY () const; + inline bool isENDEL () const; + inline bool isSNAME () const; + inline bool isCOLROW () const; + inline bool isTEXTNODE () const; + inline bool isNODE () const; + inline bool isTEXTTYPE () const; + inline bool isPRESENTATION () const; + inline bool isSPACING () const; + inline bool isSTRING () const; + inline bool isSTRANS () const; + inline bool isMAG () const; + inline bool isANGLE () const; + inline bool isREFLIBS () const; + inline bool isFONTS () const; + inline bool isPATHTYPE () const; + inline bool isGENERATIONS () const; + inline bool isATTRTABLE () const; + inline bool isSTYPTABLE () const; + inline bool isSTRTYPE () const; + inline bool isELFLAGS () const; + inline bool isELKEY () const; + inline bool isLINKTYPE () const; + inline bool isLINKKEYS () const; + inline bool isNODETYPE () const; + inline bool isPROPATTR () const; + inline bool isPROPVALUE () const; + inline bool isBOX () const; + inline bool isBOXTYPE () const; + inline bool isPLEX () const; + inline bool isBGNEXTN () const; + inline bool isENDEXTN () const; + inline bool isTAPENUM () const; + inline bool isTAPECODE () const; + inline bool isSTRCLASS () const; + inline bool isRESERVED () const; + inline bool isFORMAT () const; + inline bool isMASK () const; + inline bool isENDMASKS () const; + inline bool isLIBDIRSIZE () const; + inline bool isSRFNAME () const; + inline bool isLIBSECUR () const; + inline uint16_t getType () const; + inline uint16_t getLength () const; + inline const vector& getMasks () const; + inline const vector& getInt16s () const; + inline const vector& getInt32s () const; + inline const vector& getDoubles () const; + inline string getName () const; + void clear (); + void read ( istream* ); + void readDummy ( bool showError ); + void readUnits (); + void readLayer (); + void readStrname (); + void readXy (); + static string toStrType ( uint16_t ); + GdsRecord& operator= ( const GdsRecord& ); + private: + template< typename IntType> IntType _readInt (); + string _readString (); + double _readDouble (); + private: + istream* _stream; + uint16_t _length; + uint16_t _count; + uint16_t _type; + string _name; + vector _masks; + vector _int16s; + vector _int32s; + vector _doubles; + }; + + + inline bool GdsRecord::isHEADER () const { return (_type == HEADER ); } + inline bool GdsRecord::isBGNLIB () const { return (_type == BGNLIB ); } + inline bool GdsRecord::isLIBNAME () const { return (_type == LIBNAME ); } + inline bool GdsRecord::isUNITS () const { return (_type == UNITS ); } + inline bool GdsRecord::isENDLIB () const { return (_type == ENDLIB ); } + inline bool GdsRecord::isBGNSTR () const { return (_type == BGNSTR ); } + inline bool GdsRecord::isSTRNAME () const { return (_type == STRNAME ); } + inline bool GdsRecord::isENDSTR () const { return (_type == ENDSTR ); } + inline bool GdsRecord::isBOUNDARY () const { return (_type == BOUNDARY ); } + inline bool GdsRecord::isPATH () const { return (_type == PATH ); } + inline bool GdsRecord::isSREF () const { return (_type == SREF ); } + inline bool GdsRecord::isAREF () const { return (_type == AREF ); } + inline bool GdsRecord::isTEXT () const { return (_type == TEXT ); } + inline bool GdsRecord::isLAYER () const { return (_type == LAYER ); } + inline bool GdsRecord::isDATATYPE () const { return (_type == DATATYPE ); } + inline bool GdsRecord::isWIDTH () const { return (_type == WIDTH ); } + inline bool GdsRecord::isXY () const { return (_type == XY ); } + inline bool GdsRecord::isENDEL () const { return (_type == ENDEL ); } + inline bool GdsRecord::isSNAME () const { return (_type == SNAME ); } + inline bool GdsRecord::isCOLROW () const { return (_type == COLROW ); } + inline bool GdsRecord::isTEXTNODE () const { return (_type == TEXTNODE ); } + inline bool GdsRecord::isNODE () const { return (_type == NODE ); } + inline bool GdsRecord::isTEXTTYPE () const { return (_type == TEXTTYPE ); } + inline bool GdsRecord::isPRESENTATION () const { return (_type == PRESENTATION); } + inline bool GdsRecord::isSPACING () const { return (_type == SPACING ); } + inline bool GdsRecord::isSTRING () const { return (_type == STRING ); } + inline bool GdsRecord::isSTRANS () const { return (_type == STRANS ); } + inline bool GdsRecord::isMAG () const { return (_type == MAG ); } + inline bool GdsRecord::isANGLE () const { return (_type == ANGLE ); } + inline bool GdsRecord::isREFLIBS () const { return (_type == REFLIBS ); } + inline bool GdsRecord::isFONTS () const { return (_type == FONTS ); } + inline bool GdsRecord::isPATHTYPE () const { return (_type == PATHTYPE ); } + inline bool GdsRecord::isGENERATIONS () const { return (_type == GENERATIONS ); } + inline bool GdsRecord::isATTRTABLE () const { return (_type == ATTRTABLE ); } + inline bool GdsRecord::isSTYPTABLE () const { return (_type == STYPTABLE ); } + inline bool GdsRecord::isSTRTYPE () const { return (_type == STRTYPE ); } + inline bool GdsRecord::isELFLAGS () const { return (_type == ELFLAGS ); } + inline bool GdsRecord::isELKEY () const { return (_type == ELKEY ); } + inline bool GdsRecord::isLINKTYPE () const { return (_type == LINKTYPE ); } + inline bool GdsRecord::isLINKKEYS () const { return (_type == LINKKEYS ); } + inline bool GdsRecord::isNODETYPE () const { return (_type == NODETYPE ); } + inline bool GdsRecord::isPROPATTR () const { return (_type == PROPATTR ); } + inline bool GdsRecord::isPROPVALUE () const { return (_type == PROPVALUE ); } + inline bool GdsRecord::isBOX () const { return (_type == BOX ); } + inline bool GdsRecord::isBOXTYPE () const { return (_type == BOXTYPE ); } + inline bool GdsRecord::isPLEX () const { return (_type == PLEX ); } + inline bool GdsRecord::isBGNEXTN () const { return (_type == BGNEXTN ); } + inline bool GdsRecord::isENDEXTN () const { return (_type == ENDEXTN ); } + inline bool GdsRecord::isTAPENUM () const { return (_type == TAPENUM ); } + inline bool GdsRecord::isTAPECODE () const { return (_type == TAPECODE ); } + inline bool GdsRecord::isSTRCLASS () const { return (_type == STRCLASS ); } + inline bool GdsRecord::isRESERVED () const { return (_type == RESERVED ); } + inline bool GdsRecord::isFORMAT () const { return (_type == FORMAT ); } + inline bool GdsRecord::isMASK () const { return (_type == MASK ); } + inline bool GdsRecord::isENDMASKS () const { return (_type == ENDMASKS ); } + inline bool GdsRecord::isLIBDIRSIZE () const { return (_type == LIBDIRSIZE ); } + inline bool GdsRecord::isSRFNAME () const { return (_type == SRFNAME ); } + inline bool GdsRecord::isLIBSECUR () const { return (_type == LIBSECUR ); } + inline uint16_t GdsRecord::getType () const { return _type; } + inline uint16_t GdsRecord::getLength () const { return _length; } + inline const vector& GdsRecord::getMasks () const { return _masks; } + inline const vector& GdsRecord::getInt16s () const { return _int16s; } + inline const vector& GdsRecord::getInt32s () const { return _int32s; } + inline const vector& GdsRecord::getDoubles () const { return _doubles; } + inline string GdsRecord::getName () const { return _name; } + + + GdsRecord::GdsRecord () + : _stream (NULL) + , _length (0) + , _count (0) + , _type (0) + , _name () + , _masks () + , _int16s () + , _int32s () + , _doubles () + { } + + + void GdsRecord::clear () + { + _stream = NULL; + _length = 0; + _count = 0; + _type = 0; + _name .clear(); + _masks .clear(); + _int16s .clear(); + _int32s .clear(); + _doubles .clear(); + } + + + void GdsRecord::read ( istream* stream ) + { + clear(); + + _stream = stream; + _length = _readInt(); + _type = _readInt(); + + switch ( _type ) { + case HEADER: readDummy( false ); break; + case BGNLIB: readDummy( false ); break; + case LIBNAME: readDummy( false ); break; + case UNITS: readUnits(); break; + case ENDLIB: readDummy( false ); break; + case BGNSTR: readDummy( false ); break; + case STRNAME: readStrname(); break; + case ENDSTR: readDummy( false ); break; + case BOUNDARY: readDummy( false ); break; + case PATH: readDummy( false ); break; + case SREF: readDummy( false ); break; + case AREF: readDummy( false ); break; + case TEXT: readDummy( false ); break; + case LAYER: readLayer(); break; + case DATATYPE: readDummy( false ); break; + case WIDTH: readDummy( false ); break; + case XY: readXy(); break; + case ENDEL: readDummy( false ); break; + case SNAME: readDummy( false ); break; + case COLROW: readDummy( false ); break; + case TEXTNODE: readDummy( false ); break; + case NODE: readDummy( false ); break; + case TEXTTYPE: readDummy( false ); break; + case PRESENTATION: readDummy( false ); break; + case SPACING: readDummy( false ); break; + case STRING: readDummy( false ); break; + case STRANS: readDummy( false ); break; + case MAG: readDummy( false ); break; + case ANGLE: readDummy( false ); break; + case REFLIBS: readDummy( false ); break; + case FONTS: readDummy( false ); break; + case PATHTYPE: readDummy( false ); break; + case GENERATIONS: readDummy( false ); break; + case ATTRTABLE: readDummy( false ); break; + case STYPTABLE: readDummy( false ); break; + case STRTYPE: readDummy( false ); break; + case ELFLAGS: readDummy( false ); break; + case ELKEY: readDummy( false ); break; + case LINKTYPE: readDummy( false ); break; + case LINKKEYS: readDummy( false ); break; + case NODETYPE: readDummy( false ); break; + case PROPATTR: readDummy( false ); break; + case PROPVALUE: readDummy( false ); break; + case BOX: readDummy( false ); break; + case BOXTYPE: readDummy( false ); break; + case PLEX: readDummy( false ); break; + case BGNEXTN: readDummy( false ); break; + case ENDEXTN: readDummy( false ); break; + case TAPENUM: readDummy( false ); break; + case TAPECODE: readDummy( false ); break; + case STRCLASS: readDummy( false ); break; + case RESERVED: readDummy( false ); break; + case FORMAT: readDummy( false ); break; + case MASK: readDummy( false ); break; + case ENDMASKS: readDummy( false ); break; + case LIBDIRSIZE: readDummy( false ); break; + case SRFNAME: readDummy( false ); break; + case LIBSECUR: readDummy( false ); break; + } + + //cerr << " GdsRecord::read() " << toStrType(_type) << endl; + } + + + GdsRecord& GdsRecord::operator= ( const GdsRecord& other ) + { + _length = other._length; + _count = other._count; + _type = other._type; + _name = other._name; + _masks = other._masks; + _int16s = other._int16s; + _int32s = other._int32s; + _doubles = other._doubles; + return *this; + } + + + template< typename IntType> + IntType GdsRecord::_readInt () + { + const size_t typeSize = sizeof(IntType); + + union UType { + IntType integer; + unsigned char bytes[ typeSize ]; + }; + + char bytes[typeSize]; + _stream->read( bytes, typeSize ); + _count += typeSize; + + UType uvalue; + // Little endian (x86). + for ( size_t i=0 ; iread( bytes, 8 ); + _count += 8; + + gdsUInt64 mantisse; + for ( size_t i=0 ; i<7 ; ++i ) mantisse.bytes[i] = bytes[7-i]; + mantisse.bytes[7] = 0; + double value = mantisse.uint64; + + if (bytes[0] & 0x80) value = -value; + + int32_t exponent = (bytes[0] & 0x7f) - (64+14); + if (exponent) value *= pow( 16.0, (double)exponent ); + + return value; + } + + + string GdsRecord::_readString () + { + string s; + char c; + for ( ; _count<_length ; ++_count ) { + _stream->get( c ); + if (c != (char)0) s.push_back(c); + } + return s; + } + + + void GdsRecord::readDummy ( bool showError ) + { + char c; + for ( ; _count<_length ; ++_count ) _stream->get( c ); + + if (showError) { + cerr << Error( "GdsRecord type %s unsupported.", toStrType(_type).c_str() ) << endl; + } + } + + + void GdsRecord::readUnits () + { for ( size_t i=0 ; i<2 ; ++i ) _doubles.push_back( _readDouble() ); } + + + void GdsRecord::readStrname () + { _name = _readString(); } + + + void GdsRecord::readLayer () + { _int16s.push_back( _readInt() ); } + + + void GdsRecord::readXy () + { while ( _count < _length ) _int32s.push_back( _readInt() ); } + + + string GdsRecord::toStrType ( uint16_t type ) + { + switch ( type ) { + case HEADER: return "HEADER"; + case BGNLIB: return "BGNLIB"; + case LIBNAME: return "LIBNAME"; + case UNITS: return "UNITS"; + case ENDLIB: return "ENDLIB"; + case BGNSTR: return "BGNSTR"; + case STRNAME: return "STRNAME"; + case ENDSTR: return "ENDSTR"; + case BOUNDARY: return "BOUNDARY"; + case PATH: return "PATH"; + case SREF: return "SREF"; + case AREF: return "AREF"; + case TEXT: return "TEXT"; + case LAYER: return "LAYER"; + case DATATYPE: return "DATATYPE"; + case WIDTH: return "WIDTH"; + case XY: return "XY"; + case ENDEL: return "ENDEL"; + case SNAME: return "SNAME"; + case COLROW: return "COLROW"; + case TEXTNODE: return "TEXTNODE"; + case NODE: return "NODE"; + case TEXTTYPE: return "TEXTTYPE"; + case PRESENTATION:return "PRESENTATION"; + case SPACING: return "SPACING"; + case STRING: return "STRING"; + case STRANS: return "STRANS"; + case MAG: return "MAG"; + case ANGLE: return "ANGLE"; + case REFLIBS: return "REFLIBS"; + case FONTS: return "FONTS"; + case PATHTYPE: return "PATHTYPE"; + case GENERATIONS: return "GENERATIONS"; + case ATTRTABLE: return "ATTRTABLE"; + case STYPTABLE: return "STYPTABLE"; + case STRTYPE: return "STRTYPE"; + case ELFLAGS: return "ELFLAGS"; + case ELKEY: return "ELKEY"; + case LINKTYPE: return "LINKTYPE"; + case LINKKEYS: return "LINKKEYS"; + case NODETYPE: return "NODETYPE"; + case PROPATTR: return "PROPATTR"; + case PROPVALUE: return "PROPVALUE"; + case BOX: return "BOX"; + case BOXTYPE: return "BOXTYPE"; + case PLEX: return "PLEX"; + case BGNEXTN: return "BGNEXTN"; + case ENDEXTN: return "ENDEXTN"; + case TAPENUM: return "TAPENUM"; + case TAPECODE: return "TAPECODE"; + case STRCLASS: return "STRCLASS"; + case RESERVED: return "RESERVED"; + case FORMAT: return "FORMAT"; + case MASK: return "MASK"; + case ENDMASKS: return "ENDMASKS"; + case LIBDIRSIZE: return "LIBDIRSIZE"; + case SRFNAME: return "SRFNAME"; + case LIBSECUR: return "LIBSECUR"; + } + + ostringstream error; + error << "undefined GDS record type (0x" << hex << type << ")"; + return error.str(); + } + + + istream& operator>> ( istream& stream, GdsRecord& record ) + { record.read( &stream ); return stream; } + + +// ------------------------------------------------------------------- +// Class : "::GdsStream". + + class GdsStream { + public: + static const Layer* gdsToLayer ( uint16_t ); + public: + static void _staticInit (); + GdsStream ( string gdsPath ); + inline bool isValidSyntax () const; + bool misplacedRecord (); + bool read ( Library* ); + bool readFormatType (); + bool readStructure (); + bool readBoundary (); + bool readPath (); + bool readSref (); + bool readAref (); + bool readNode (); + bool readBox (); + bool readText (); + bool readTextbody (); + bool readStrans (); + bool readProperty (); + void xyToComponent ( const Layer* ); + Net* anonymousNet (); + private: + static vector _gdsLayerTable; + string _gdsPath; + ifstream _stream; + GdsRecord _record; + Library* _library; + Cell* _cell; + DbU::Unit _scale; + int64_t _netCount; + bool _validSyntax; + }; + + + vector GdsStream::_gdsLayerTable; + + + void GdsStream::_staticInit () + { + _gdsLayerTable = vector( 64, NULL ); + for ( const BasicLayer* layer : DataBase::getDB()->getTechnology()->getBasicLayers() ) { + unsigned int gdsNumber = layer->getGds2Layer(); + if (gdsNumber < 64) _gdsLayerTable[gdsNumber] = layer; + } + } + + + const Layer* GdsStream::gdsToLayer ( uint16_t gdsLayer ) + { return (gdsLayer < _gdsLayerTable.size()) ? _gdsLayerTable[gdsLayer] : NULL; } + + + inline bool GdsStream::isValidSyntax () const { return _validSyntax; } + + + GdsStream::GdsStream ( string gdsPath ) + : _gdsPath (gdsPath) + , _stream () + , _record () + , _library (NULL) + , _cell (NULL) + , _scale (1) + , _netCount (0) + , _validSyntax(true) + { + if (_gdsLayerTable.empty()) _staticInit(); + + _stream.open( gdsPath, ios_base::in ); + + _stream >> _record; + if (not _record.isHEADER()) { + cerr << Error( "GdsStream::GdsStream(): First record is not a HEADER.\n" + " in \"%s\"" + , _gdsPath.c_str() ) << endl; + _validSyntax = false; + return; + } + _stream >> _record; + } + + + bool GdsStream::misplacedRecord () + { + cerr << Error( "GdsStream: Misplaced record %s.\n" + " in \"%s\"" + , GdsRecord::toStrType(_record.getType()).c_str() + , _gdsPath.c_str() ) << endl; + _validSyntax = false; + return _validSyntax; + } + + + bool GdsStream::read ( Library* library ) + { + //cerr << "GdsStream::read(Library*)" << endl; + + _library = library; + + if (not _record.isBGNLIB()) { + cerr << Error( "GdsStream::read(Library*): Starting record is not a BGNLIB.\n" + " in \"%s\"" + , _gdsPath.c_str() ) << endl; + _validSyntax = false; + return _validSyntax; + } + _stream >> _record; + + if (_record.isLIBDIRSIZE ()) { _stream >> _record; } + if (_record.isSRFNAME ()) { _stream >> _record; } + if (_record.isLIBSECUR ()) { _stream >> _record; } + if (_record.isLIBNAME ()) { _stream >> _record; } + else { + cerr << Error( "GdsStream::read(Library*): Missing LIBNAME record.\n" + " in \"%s\"" + , _gdsPath.c_str() ) << endl; + _validSyntax = false; + return _validSyntax; + } + if (_record.isREFLIBS ()) { _stream >> _record; } + if (_record.isFONTS ()) { _stream >> _record; } + if (_record.isATTRTABLE ()) { _stream >> _record; } + if (_record.isGENERATIONS()) { _stream >> _record; } + if (_record.isFORMAT ()) { readFormatType(); if (not _validSyntax) return _validSyntax; } + + if (_record.isUNITS()) { + _scale = DbU::fromPhysical( _record.getDoubles()[1], DbU::Unity ); + _stream >> _record; + } + + while ( _validSyntax and _record.isBGNSTR() ) { + _stream >> _record; + readStructure(); + } + + if (_validSyntax and not _record.isENDLIB()) { misplacedRecord(); } + + _library = NULL; + //cerr << "GdsStream::read(Library*) - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readFormatType () + { + //cerr << "GdsStream::readFormatType()" << endl; + + if (_record.isMASK()) { + _stream >> _record; + while ( _record.isMASK() ) { + _stream >> _record; + } + + if (_record.isENDMASKS()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + } + + //cerr << "GdsStream::readFormatType() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readStructure () + { + //cerr << "GdsStream::readStructure()" << endl; + + if (_record.isSTRNAME()) { + if (_library) { + _cell = _library->getCell( _record.getName() ); + if (not _cell) { + cerr << Warning( "GdsStream::readStructure(): No Cell named \"%s\" in Library \"%s\" (skipped)." + , _record.getName().c_str() + , getString(_library).c_str() + ) << endl; + } + } + _stream >> _record; + } + + if (_record.isSTRCLASS()) { _stream >> _record; } + + while ( not _record.isENDSTR() ) { + switch ( _record.getType() ) { + case GdsRecord::BOUNDARY: _stream >> _record; readBoundary(); break; + case GdsRecord::PATH: _stream >> _record; readPath (); break; + case GdsRecord::SREF: _stream >> _record; readSref (); break; + case GdsRecord::AREF: _stream >> _record; readAref (); break; + case GdsRecord::TEXT: _stream >> _record; readText (); break; + case GdsRecord::NODE: _stream >> _record; readNode (); break; + case GdsRecord::BOX: _stream >> _record; readBox (); break; + case GdsRecord::PROPATTR: _stream >> _record; readProperty(); break; + } + if (_record.isENDEL()) { _stream >> _record; } + else { + _validSyntax = false; break; + } + } + + if (_validSyntax) _stream >> _record; + + _cell = NULL; + //cerr << "GdsStream::readStructure() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readText () + { + //cerr << "GdsStream::readText()" << endl; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isLAYER ()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + readTextbody(); + + //cerr << "GdsStream::readText() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readTextbody () + { + //cerr << "GdsStream::readTextbody()" << endl; + + if (_record.isTEXTTYPE()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + if (_record.isPRESENTATION()) { _stream >> _record; } + if (_record.isPATH ()) { _stream >> _record; } + if (_record.isWIDTH ()) { _stream >> _record; } + + if (_record.isSTRANS()) { + _stream >> _record; + readStrans(); + if (not _validSyntax) return _validSyntax; + } + + if (_record.isXY()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + if (_record.isSTRING()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + //cerr << "GdsStream::readTextbody() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readStrans () + { + //cerr << "GdsStream::readStrans()" << endl; + + if (_record.isMAG ()) { _stream >> _record; } + if (_record.isANGLE()) { _stream >> _record; } + + //cerr << "GdsStream::readStrans() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readBoundary () + { + //cerr << "GdsStream::readBoundary()" << endl; + + const Layer* layer = NULL; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isLAYER()) { + layer = gdsToLayer( _record.getInt16s()[0] ); + if (not layer) { + cerr << Error( "GdsStream::readBoundary(): No BasicLayer id:%d in GDS conversion table (skipped)." + , _record.getInt16s()[0] + ) << endl; + } + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isDATATYPE()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + if (_record.isXY()) { + if (_cell and layer) xyToComponent( layer ); + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + //cerr << "GdsStream::readBoundary() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readPath () + { + //cerr << "GdsStream::readPath()" << endl; + + const Layer* layer = NULL; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isLAYER()) { + layer = gdsToLayer( _record.getInt16s()[0] ); + if (not layer) { + cerr << Error( "GdsStream::readPath(): No BasicLayer id \"%d\" in GDS conversion table (skipped)." + , _record.getInt16s()[0] + ) << endl; + } + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isDATATYPE()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + if (_record.isPATHTYPE()) { _stream >> _record; } + if (_record.isWIDTH ()) { _stream >> _record; } + if (_record.isBGNEXTN ()) { _stream >> _record; } + if (_record.isENDEXTN ()) { _stream >> _record; } + + if (_record.isXY()) { + if (_cell and layer) xyToComponent( layer ); + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + //cerr << "GdsStream::readPath() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readSref () + { + //cerr << "GdsStream::readSref()" << endl; + + const Layer* layer = NULL; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isSNAME()) { + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isSTRANS()) { + _stream >> _record; + readStrans(); + if (not _validSyntax) return _validSyntax; + } + + if (_record.isXY()) { + if (_cell and layer) xyToComponent( layer ); + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + //cerr << "GdsStream::readSref() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readAref () + { + //cerr << "GdsStream::readAref()" << endl; + + const Layer* layer = NULL; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isSNAME()) { + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isSTRANS()) { + _stream >> _record; + readStrans(); + if (not _validSyntax) return _validSyntax; + } + + if (_record.isCOLROW()) { + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isXY()) { + if (_cell and layer) xyToComponent( layer ); + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + //cerr << "GdsStream::readAref() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readNode () + { + //cerr << "GdsStream::readNode()" << endl; + + const Layer* layer = NULL; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isLAYER ()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + if (_record.isNODETYPE()) { + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isXY()) { + if (_cell and layer) xyToComponent( layer ); + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + //cerr << "GdsStream::readNode() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readBox () + { + //cerr << "GdsStream::readBox()" << endl; + + const Layer* layer = NULL; + + if (_record.isELFLAGS()) { _stream >> _record; } + if (_record.isPLEX ()) { _stream >> _record; } + + if (_record.isLAYER ()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + if (_record.isBOXTYPE()) { + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + if (_record.isXY()) { + if (_cell and layer) xyToComponent( layer ); + _stream >> _record; + } else { + _validSyntax = false; return _validSyntax; + } + + //cerr << "GdsStream::readBox() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + bool GdsStream::readProperty () + { + //cerr << "GdsStream::readProperty()" << endl; + + if (_record.isPROPVALUE ()) { _stream >> _record; } + else { _validSyntax = false; return _validSyntax; } + + //cerr << "GdsStream::readProperty() - return:" << _validSyntax << endl; + return _validSyntax; + } + + + void GdsStream::xyToComponent ( const Layer* layer ) + { + vector points; + vector coordinates = _record.getInt32s(); + for ( size_t i=0 ; i 2) { + bool isRectilinear = true; + for ( size_t i=1 ; i +#include + + +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. diff --git a/crlcore/src/pyCRL/crlcore/PyGds.h b/crlcore/src/pyCRL/crlcore/PyGds.h new file mode 100644 index 00000000..5ade37c9 --- /dev/null +++ b/crlcore/src/pyCRL/crlcore/PyGds.h @@ -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 diff --git a/documentation/examples/scripts/diagonals.py b/documentation/examples/scripts/diagonals.py index 9c2311c3..a57865b2 100644 --- a/documentation/examples/scripts/diagonals.py +++ b/documentation/examples/scripts/diagonals.py @@ -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 diff --git a/documentation/examples/scripts/fulladder.py b/documentation/examples/scripts/fulladder.py index 8155c099..c4154b5a 100644 --- a/documentation/examples/scripts/fulladder.py +++ b/documentation/examples/scripts/fulladder.py @@ -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 diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index b6c2e920..09c4c720 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -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 diff --git a/hurricane/src/hurricane/Component.cpp b/hurricane/src/hurricane/Component.cpp index 23678d95..8548f38d 100644 --- a/hurricane/src/hurricane/Component.cpp +++ b/hurricane/src/hurricane/Component.cpp @@ -280,6 +280,57 @@ class Component_SlaveComponents : public Collection { }; +// ------------------------------------------------------------------- +// 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 // ************************************************ { diff --git a/hurricane/src/hurricane/Diagonal.cpp b/hurricane/src/hurricane/Diagonal.cpp index 3b02597a..833e9cec 100644 --- a/hurricane/src/hurricane/Diagonal.cpp +++ b/hurricane/src/hurricane/Diagonal.cpp @@ -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". diff --git a/hurricane/src/hurricane/Polygon.cpp b/hurricane/src/hurricane/Polygon.cpp index 65bc9e6d..e832bad0 100644 --- a/hurricane/src/hurricane/Polygon.cpp +++ b/hurricane/src/hurricane/Polygon.cpp @@ -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 ) { diff --git a/hurricane/src/hurricane/Rectilinear.cpp b/hurricane/src/hurricane/Rectilinear.cpp new file mode 100644 index 00000000..68d21855 --- /dev/null +++ b/hurricane/src/hurricane/Rectilinear.cpp @@ -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 +// . +// +// +-----------------------------------------------------------------+ +// | 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& points ) + : Super (net) + , _layer (layer) + , _points(points) + { } + + + Rectilinear* Rectilinear::create ( Net* net, const Layer* layer, const vector& points ) + { + if (not layer) + throw Error( "Rectilinear::create(): Can't create, NULL layer" ); + + for ( size_t i=0 ; i_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& points ) + { + for ( size_t i=0 ; igetName() ); + } + + + 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 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 points; + + // Have to loop over all the points. + //points.push_back( get(stack,".Point") ); + + Rectilinear* rectilinear = Rectilinear::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , points + ); + + JsonNet* jnet = jget( stack ); + if (jnet) { + jnet->addHookLink( rectilinear->getBodyHook (), jsonId, get(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. diff --git a/hurricane/src/hurricane/hurricane/Box.h b/hurricane/src/hurricane/hurricane/Box.h index 0c5daf39..cbe646fe 100644 --- a/hurricane/src/hurricane/hurricane/Box.h +++ b/hurricane/src/hurricane/hurricane/Box.h @@ -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);}; diff --git a/hurricane/src/hurricane/hurricane/Component.h b/hurricane/src/hurricane/hurricane/Component.h index faf9118a..328e865c 100644 --- a/hurricane/src/hurricane/hurricane/Component.h +++ b/hurricane/src/hurricane/hurricane/Component.h @@ -17,136 +17,167 @@ // not, see . // **************************************************************************************************** -#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 diff --git a/hurricane/src/hurricane/hurricane/Diagonal.h b/hurricane/src/hurricane/hurricane/Diagonal.h index 4ae70c9f..f87d43d2 100644 --- a/hurricane/src/hurricane/hurricane/Diagonal.h +++ b/hurricane/src/hurricane/hurricane/Diagonal.h @@ -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". diff --git a/hurricane/src/hurricane/hurricane/Polygon.h b/hurricane/src/hurricane/hurricane/Polygon.h index 03542970..0a885777 100644 --- a/hurricane/src/hurricane/hurricane/Polygon.h +++ b/hurricane/src/hurricane/hurricane/Polygon.h @@ -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& ); 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& getPoints () const; inline const vector& 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&, 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::getEdges () const { return _edges; } inline const vector& 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); } diff --git a/hurricane/src/hurricane/hurricane/Rectilinear.h b/hurricane/src/hurricane/hurricane/Rectilinear.h new file mode 100644 index 00000000..670e4a85 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/Rectilinear.h @@ -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 +// . +// +// +-----------------------------------------------------------------+ +// | 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& ); + // 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& ); + // 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& ); + private: + const Layer* _layer; + vector _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 diff --git a/hurricane/src/isobar/CMakeLists.txt b/hurricane/src/isobar/CMakeLists.txt index 22612fe2..5a078754 100644 --- a/hurricane/src/isobar/CMakeLists.txt +++ b/hurricane/src/isobar/CMakeLists.txt @@ -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 diff --git a/hurricane/src/isobar/PyHurricane.cpp b/hurricane/src/isobar/PyHurricane.cpp index 240470c0..a3e0aff4 100644 --- a/hurricane/src/isobar/PyHurricane.cpp +++ b/hurricane/src/isobar/PyHurricane.cpp @@ -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 , "" , false, "comp" ); __cs.addType ( "pad " , &PyTypePad , "" , false, "comp" ); __cs.addType ( "diagonal" , &PyTypeDiagonal , "" , false, "comp" ); + __cs.addType ( "rectilin" , &PyTypeRectilinear , "" , false, "comp" ); __cs.addType ( "polygon" , &PyTypePolygon , "" , false, "comp" ); __cs.addType ( "segmentCol" , &PyTypeSegmentCollection , "" , false ); __cs.addType ( "db" , &PyTypeDataBase , "" , 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 ); diff --git a/hurricane/src/isobar/PyRectilinear.cpp b/hurricane/src/isobar/PyRectilinear.cpp new file mode 100644 index 00000000..f0d518e1 --- /dev/null +++ b/hurricane/src/isobar/PyRectilinear.cpp @@ -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& v ) + { + if (not PyList_Check(list)) return false; + + int length = PyList_Size( list ); + for ( int i=0 ; iob_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 points; + if (not ListToVector(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 points; + if (not ListToVector(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. diff --git a/hurricane/src/isobar/hurricane/isobar/PyRectilinear.h b/hurricane/src/isobar/hurricane/isobar/PyRectilinear.h new file mode 100644 index 00000000..a3938f19 --- /dev/null +++ b/hurricane/src/isobar/hurricane/isobar/PyRectilinear.h @@ -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 diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index 2083805f..57a2937c 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -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(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(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& 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(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;