From e1c5366fefab1d025a7536778c168fceaa68e0bd Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 8 Nov 2021 21:45:50 +0000 Subject: [PATCH 1/9] crlcore: Add Python bindings for LEF export Signed-off-by: gatecat --- crlcore/src/pyCRL/CMakeLists.txt | 2 + crlcore/src/pyCRL/PyCRL.cpp | 7 +- crlcore/src/pyCRL/PyLefExport.cpp | 108 ++++++++++++++++++++++++ crlcore/src/pyCRL/crlcore/PyLefExport.h | 55 ++++++++++++ 4 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 crlcore/src/pyCRL/PyLefExport.cpp create mode 100644 crlcore/src/pyCRL/crlcore/PyLefExport.h diff --git a/crlcore/src/pyCRL/CMakeLists.txt b/crlcore/src/pyCRL/CMakeLists.txt index ec6aad3a..36358b17 100644 --- a/crlcore/src/pyCRL/CMakeLists.txt +++ b/crlcore/src/pyCRL/CMakeLists.txt @@ -50,6 +50,7 @@ PyGds.cpp PyLefImport.cpp PyDefImport.cpp + PyLefExport.cpp ) set( pyIncludes crlcore/PySystem.h crlcore/PyBanner.h @@ -72,6 +73,7 @@ crlcore/PyGds.h crlcore/PyLefImport.h crlcore/PyDefImport.h + crlcore/PyLefExport.h ) # target_link_libraries ( crlcore ${HURRICANE_PYTHON_NEW_LIBRARIES} # ${HURRICANE_PYTHON_LIBRARIES} diff --git a/crlcore/src/pyCRL/PyCRL.cpp b/crlcore/src/pyCRL/PyCRL.cpp index 673f7676..a4979fdf 100644 --- a/crlcore/src/pyCRL/PyCRL.cpp +++ b/crlcore/src/pyCRL/PyCRL.cpp @@ -36,6 +36,7 @@ #include "crlcore/PyBlif.h" #include "crlcore/PyGds.h" #include "crlcore/PyLefImport.h" +#include "crlcore/PyLefExport.h" #include "crlcore/PyDefImport.h" #include "crlcore/VhdlEntity.h" @@ -146,6 +147,7 @@ extern "C" { PyGds_LinkPyType (); PyLefImport_LinkPyType (); PyDefImport_LinkPyType (); + PyLefExport_LinkPyType (); PYTYPE_READY ( System ); PYTYPE_READY ( Banner ); @@ -169,7 +171,8 @@ extern "C" { PYTYPE_READY ( Gds ); PYTYPE_READY ( LefImport ); PYTYPE_READY ( DefImport ); - + PYTYPE_READY ( LefExport ); + // Identifier string can take up to 10 characters. __cs.addType ( "alcLib" , &PyTypeAllianceLibrary , "" , false ); __cs.addType ( "alcEnv" , &PyTypeEnvironment , "" , false ); @@ -229,6 +232,8 @@ extern "C" { PyModule_AddObject ( module, "LefImport", (PyObject*)&PyTypeLefImport ); Py_INCREF ( &PyTypeDefImport ); PyModule_AddObject ( module, "DefImport", (PyObject*)&PyTypeDefImport ); + Py_INCREF ( &PyTypeLefExport ); + PyModule_AddObject ( module, "LefExport", (PyObject*)&PyTypeLefExport ); PyCatalog_postModuleInit (); PyEnvironment_postModuleInit (); diff --git a/crlcore/src/pyCRL/PyLefExport.cpp b/crlcore/src/pyCRL/PyLefExport.cpp new file mode 100644 index 00000000..9008d030 --- /dev/null +++ b/crlcore/src/pyCRL/PyLefExport.cpp @@ -0,0 +1,108 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-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 : "./PyLefExport.cpp" | +// +-----------------------------------------------------------------+ + + +#include "crlcore/PyLefExport.h" +#include "hurricane/isobar/PyLibrary.h" +#include +#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 Hurricane::Library; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::getPyHash; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::__cs; + using Isobar::PyTypeLibrary; + using Isobar::PyLibrary; + + +extern "C" { + + +#if defined(__PYTHON_MODULE__) + +// +=================================================================+ +// | "PyLefExport" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyLefExport_drive ( PyObject*, PyObject* args ) + { + cdebug_log(30,0) << "PyLefExport_drive()" << endl; + + PyLibrary* pyLibrary = NULL; + + HTRY + unsigned int flags = 0; + + if (PyArg_ParseTuple( args, "O!I:LefExport.drive", &PyTypeLibrary, &pyLibrary, &flags)) { + LefExport::drive( PYLIBRARY_O(pyLibrary) , flags ); + } else { + PyErr_SetString ( ConstructorError, "LefExport.drive(): Bad type or bad number of parameters." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + // Standart Destroy (Attribute). + + + PyMethodDef PyLefExport_Methods[] = + { { "drive" , (PyCFunction)PyLefExport_drive , METH_VARARGS|METH_STATIC + , "Save a complete Cadence LEF library." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + NoObjectDeleteMethod(LefExport) + PyTypeObjectLinkPyTypeWithoutObject(LefExport,LefExport) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyLefExport" Shared Library Code Part | +// +=================================================================+ + + // Type Definition. + PyTypeObjectDefinitionsOfModule(CRL,LefExport) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // CRL namespace. diff --git a/crlcore/src/pyCRL/crlcore/PyLefExport.h b/crlcore/src/pyCRL/crlcore/PyLefExport.h new file mode 100644 index 00000000..edaefcdf --- /dev/null +++ b/crlcore/src/pyCRL/crlcore/PyLefExport.h @@ -0,0 +1,55 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-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++ Header : "./crlcore/PyLefExport.h" | +// +-----------------------------------------------------------------+ + + +#ifndef CRL_PY_LEF_EXPORT_H +#define CRL_PY_LEF_EXPORT_H + +#include "hurricane/isobar/PyHurricane.h" +#include "crlcore/LefExport.h" + + +namespace CRL { + +extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyLefExport". + + typedef struct { + PyObject_HEAD + } PyLefExport; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyCRL.ccp". + + extern PyTypeObject PyTypeLefExport; + extern PyMethodDef PyLefExport_Methods[]; + + extern void PyLefExport_LinkPyType(); + + +#define IsPyLefExport(v) ( (v)->ob_type == &PyTypeLefExport ) +#define PY_LEFEXPORT(v) ( (PyLefExport*)(v) ) + + +} // extern "C". + +} // CRL namespace. + +#endif // CRL_PY_LEF_EXPORT_H From 2f1caca8122260893897bc11a87f23dacba8db53 Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 8 Nov 2021 22:15:43 +0000 Subject: [PATCH 2/9] lefexport: Make it useful for real processes Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/LefExport.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/crlcore/src/ccore/lefdef/LefExport.cpp b/crlcore/src/ccore/lefdef/LefExport.cpp index b3573c22..ac8b91dc 100644 --- a/crlcore/src/ccore/lefdef/LefExport.cpp +++ b/crlcore/src/ccore/lefdef/LefExport.cpp @@ -119,7 +119,7 @@ namespace { int LefDriver::getUnits () { return _units; } - double LefDriver::toLefUnits ( DbU::Unit u ) { return DbU::getLambda(u)/**getUnits()*/; } + double LefDriver::toLefUnits ( DbU::Unit u ) { return DbU::toMicrons(u)/**getUnits()*/; } DbU::Unit LefDriver::getSliceHeight () { return _sliceHeight; } DbU::Unit LefDriver::getPitchWidth () { return _pitchWidth; }; inline AllianceFramework* LefDriver::getFramework () { return _framework; } @@ -144,9 +144,13 @@ namespace { _pitchWidth = cg->getPitch (); } + _units = DbU::toGrid(DbU::fromMicrons(1.0)); + _status = lefwInitCbk ( _lefStream ); if ( _status != 0 ) return; + + lefwSetVersionCbk ( _versionCbk ); lefwSetBusBitCharsCbk ( _busBitCharsCbk ); lefwSetDividerCharCbk ( _dividerCharCbk ); @@ -207,7 +211,7 @@ namespace { _status = lefwLayerRoutingPitch ( toLefUnits(lg->getPitch()) ); if ( _status != 0 ) return _status; - _status = lefwLayerRoutingSpacing ( toLefUnits(lg->getPitch()-lg->getWireWidth()-DbU::lambda(1.0)) ); + _status = lefwLayerRoutingSpacing ( toLefUnits(lg->getPitch()-lg->getWireWidth()/*-DbU::lambda(1.0)*/) ); if ( _status != 0 ) return _status; return _status = lefwEndLayerRouting ( layerName.c_str() ); @@ -491,7 +495,7 @@ namespace { int status = 0; for ( size_t ilayer=0 ; ilayer 0 ) { - status = driver->_driveCutLayer ( technology->getCutBelow(rg[ilayer]->getLayer()) ); + status = driver->_driveCutLayer ( technology->getCutBelow(rg[ilayer]->getLayer(), false) ); if ( status != 0 ) return driver->checkStatus(status); } @@ -566,7 +570,7 @@ namespace { // The driver puts it before UNITS, which seems to displease Cadence Encounter. // So, as long as it doesn't prevent Encounter to works, disable it. LefDriver* driver = (LefDriver*)udata; - return driver->checkStatus ( lefwManufacturingGrid ( LefDriver::toLefUnits(DbU::fromLambda(0.5)) ) ); + return driver->checkStatus ( lefwManufacturingGrid ( LefDriver::toLefUnits(DbU::fromGrid(1.0)) ) ); #else return 0; #endif @@ -604,10 +608,12 @@ namespace { int status = 0; for ( size_t ilayer=1 ; ilayergetLayer(); - const Layer* bottomLayer = topLayer->getMetalBelow(); - const Layer* cutLayer = topLayer->getCutBelow(); + const Layer* bottomLayer = topLayer->getMetalBelow(false); + const Layer* cutLayer = topLayer->getCutBelow(false); const Layer* viaLayer = technology->getViaBetween ( topLayer, bottomLayer ); + if ( !viaLayer ) continue; + status = lefwStartVia ( getString(viaLayer->getName()).c_str(), "DEFAULT" ); if ( status != 0 ) return driver->checkStatus(status); From 4884a5d6dcbd14513bfcc21b43e14b18fcbc2b87 Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 23 Nov 2021 10:23:41 +0000 Subject: [PATCH 3/9] crlcore: Add Python bindings for DEF export Signed-off-by: gatecat --- crlcore/src/pyCRL/CMakeLists.txt | 2 + crlcore/src/pyCRL/PyCRL.cpp | 5 ++ crlcore/src/pyCRL/PyDefExport.cpp | 108 ++++++++++++++++++++++++ crlcore/src/pyCRL/crlcore/PyDefExport.h | 55 ++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 crlcore/src/pyCRL/PyDefExport.cpp create mode 100644 crlcore/src/pyCRL/crlcore/PyDefExport.h diff --git a/crlcore/src/pyCRL/CMakeLists.txt b/crlcore/src/pyCRL/CMakeLists.txt index 36358b17..1ca6e829 100644 --- a/crlcore/src/pyCRL/CMakeLists.txt +++ b/crlcore/src/pyCRL/CMakeLists.txt @@ -51,6 +51,7 @@ PyLefImport.cpp PyDefImport.cpp PyLefExport.cpp + PyDefExport.cpp ) set( pyIncludes crlcore/PySystem.h crlcore/PyBanner.h @@ -74,6 +75,7 @@ crlcore/PyLefImport.h crlcore/PyDefImport.h crlcore/PyLefExport.h + crlcore/PyDefExport.h ) # target_link_libraries ( crlcore ${HURRICANE_PYTHON_NEW_LIBRARIES} # ${HURRICANE_PYTHON_LIBRARIES} diff --git a/crlcore/src/pyCRL/PyCRL.cpp b/crlcore/src/pyCRL/PyCRL.cpp index a4979fdf..22de2ee2 100644 --- a/crlcore/src/pyCRL/PyCRL.cpp +++ b/crlcore/src/pyCRL/PyCRL.cpp @@ -38,6 +38,7 @@ #include "crlcore/PyLefImport.h" #include "crlcore/PyLefExport.h" #include "crlcore/PyDefImport.h" +#include "crlcore/PyDefExport.h" #include "crlcore/VhdlEntity.h" @@ -148,6 +149,7 @@ extern "C" { PyLefImport_LinkPyType (); PyDefImport_LinkPyType (); PyLefExport_LinkPyType (); + PyDefExport_LinkPyType (); PYTYPE_READY ( System ); PYTYPE_READY ( Banner ); @@ -172,6 +174,7 @@ extern "C" { PYTYPE_READY ( LefImport ); PYTYPE_READY ( DefImport ); PYTYPE_READY ( LefExport ); + PYTYPE_READY ( DefExport ); // Identifier string can take up to 10 characters. __cs.addType ( "alcLib" , &PyTypeAllianceLibrary , "" , false ); @@ -234,6 +237,8 @@ extern "C" { PyModule_AddObject ( module, "DefImport", (PyObject*)&PyTypeDefImport ); Py_INCREF ( &PyTypeLefExport ); PyModule_AddObject ( module, "LefExport", (PyObject*)&PyTypeLefExport ); + Py_INCREF ( &PyTypeDefExport ); + PyModule_AddObject ( module, "DefExport", (PyObject*)&PyTypeDefExport ); PyCatalog_postModuleInit (); PyEnvironment_postModuleInit (); diff --git a/crlcore/src/pyCRL/PyDefExport.cpp b/crlcore/src/pyCRL/PyDefExport.cpp new file mode 100644 index 00000000..5c8ee79f --- /dev/null +++ b/crlcore/src/pyCRL/PyDefExport.cpp @@ -0,0 +1,108 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-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 : "./PyDefExport.cpp" | +// +-----------------------------------------------------------------+ + + +#include "crlcore/PyDefExport.h" +#include "hurricane/isobar/PyCell.h" +#include +#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 Hurricane::Cell; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::getPyHash; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::__cs; + using Isobar::PyTypeCell; + using Isobar::PyCell; + + +extern "C" { + + +#if defined(__PYTHON_MODULE__) + +// +=================================================================+ +// | "PyDefExport" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyDefExport_drive ( PyObject*, PyObject* args ) + { + cdebug_log(30,0) << "PyDefExport_drive()" << endl; + + PyCell* pyCell = NULL; + + HTRY + unsigned int flags = 0; + + if (PyArg_ParseTuple( args, "O!I:DefExport.drive", &PyTypeCell, &pyCell, &flags)) { + DefExport::drive( PYCELL_O(pyCell) , flags ); + } else { + PyErr_SetString ( ConstructorError, "DefExport.drive(): Bad type or bad number of parameters." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + // Standart Destroy (Attribute). + + + PyMethodDef PyDefExport_Methods[] = + { { "drive" , (PyCFunction)PyDefExport_drive , METH_VARARGS|METH_STATIC + , "Save a complete Cadence DEF design." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + NoObjectDeleteMethod(DefExport) + PyTypeObjectLinkPyTypeWithoutObject(DefExport,DefExport) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyDefExport" Shared Library Code Part | +// +=================================================================+ + + // Type Definition. + PyTypeObjectDefinitionsOfModule(CRL,DefExport) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // CRL namespace. diff --git a/crlcore/src/pyCRL/crlcore/PyDefExport.h b/crlcore/src/pyCRL/crlcore/PyDefExport.h new file mode 100644 index 00000000..cb804493 --- /dev/null +++ b/crlcore/src/pyCRL/crlcore/PyDefExport.h @@ -0,0 +1,55 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2017-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++ Header : "./crlcore/PyDefExport.h" | +// +-----------------------------------------------------------------+ + + +#ifndef CRL_PY_DEF_EXPORT_H +#define CRL_PY_DEF_EXPORT_H + +#include "hurricane/isobar/PyHurricane.h" +#include "crlcore/DefExport.h" + + +namespace CRL { + +extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyDefExport". + + typedef struct { + PyObject_HEAD + } PyDefExport; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyCRL.ccp". + + extern PyTypeObject PyTypeDefExport; + extern PyMethodDef PyDefExport_Methods[]; + + extern void PyDefExport_LinkPyType(); + + +#define IsPyDefExport(v) ( (v)->ob_type == &PyTypeDefExport ) +#define PY_DEFEXPORT(v) ( (PyDefExport*)(v) ) + + +} // extern "C". + +} // CRL namespace. + +#endif // CRL_PY_DEF_EXPORT_H From ddb684bfe11bd4ac4099da697a4800aa076dbaf0 Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 23 Nov 2021 10:52:31 +0000 Subject: [PATCH 4/9] defexport: Make it useful for real processes Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/DefExport.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index b29c6a20..92d1c7c0 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -218,6 +218,7 @@ namespace { _sliceHeight = cg->getSliceHeight (); _pitchWidth = cg->getPitch (); + _units = DbU::toGrid(DbU::fromMicrons(1.0)); _status = defwInitCbk ( _defStream ); if ( _status != 0 ) return; @@ -331,7 +332,7 @@ namespace { int DefDriver::_technologyCbk ( defwCallbackType_e, defiUserData udata ) { DefDriver* driver = (DefDriver*)udata; - return driver->checkStatus ( defwTechnology("symbolic") ); + return driver->checkStatus ( defwTechnology( getString(driver->getCell()->getLibrary()->getName()).c_str() ) ); } From a8dd84838b75ad4f719664944fa42dd7fd5e9ea9 Mon Sep 17 00:00:00 2001 From: gatecat Date: Tue, 23 Nov 2021 18:50:00 +0000 Subject: [PATCH 5/9] def: Fix export units for non-lambda processes Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/DefExport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index 92d1c7c0..a17ae7c0 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -150,7 +150,7 @@ namespace { int DefDriver::getUnits () { return _units; } - int DefDriver::toDefUnits ( DbU::Unit u ) { return (int)round(DbU::getLambda(u)*getUnits()); } + int DefDriver::toDefUnits ( DbU::Unit u ) { return (int)round(DbU::getGrid(u)); } DbU::Unit DefDriver::getSliceHeight () { return _sliceHeight; } DbU::Unit DefDriver::getPitchWidth () { return _pitchWidth; }; inline Cell* DefDriver::getCell () { return _cell; } From 4250c5bec76118c547ff89c0c67bb652341ac34a Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 10 Jan 2022 18:43:59 +0000 Subject: [PATCH 6/9] def: Fix export of pins Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/DefExport.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index a17ae7c0..79d03ecd 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -601,10 +601,18 @@ namespace { if ( status != 0 ) return driver->checkStatus(status); for ( RoutingPad* rp : net->getRoutingPads() ) { - status = defwNetConnection ( extractInstanceName(rp).c_str() - , getString(static_cast(rp->getPlugOccurrence().getEntity())->getMasterNet()->getName()).c_str() - , 0 - ); + Plug *plug = dynamic_cast(rp->getPlugOccurrence().getEntity()); + if (plug) { + status = defwNetConnection ( extractInstanceName(rp).c_str() + , getString(plug->getMasterNet()->getName()).c_str() + , 0 + ); + } else { + Pin *pin = dynamic_cast(rp->getPlugOccurrence().getEntity()); + if (!pin) + throw Error("RP PlugOccurrence neither a plug nor a pin!"); + // TODO: do we need to write something ? + } if ( status != 0 ) return driver->checkStatus(status); } From c4ef465c414d2b3f39346d894adf30af8e31a79a Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 10 Jan 2022 19:45:04 +0000 Subject: [PATCH 7/9] def: Fix order of instance transforms Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/DefExport.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index 79d03ecd..d5b9351c 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -178,12 +178,13 @@ namespace { void DefDriver::toDefCoordinates ( Instance* instance, Transformation transf, int& statusX, int& statusY, int& statusOrient ) { - instance->getTransformation().applyOn( transf ); - statusX = toDefUnits ( transf.getTx() ); - statusY = toDefUnits ( transf.getTy() ); - statusOrient = toDefOrient( transf.getOrientation() ); + Transformation inst_transf = instance->getTransformation(); + transf.applyOn( inst_transf ); + statusX = toDefUnits ( inst_transf.getTx() ); + statusY = toDefUnits ( inst_transf.getTy() ); + statusOrient = toDefOrient( inst_transf.getOrientation() ); - switch ( transf.getOrientation() ) { + switch ( inst_transf.getOrientation() ) { case Transformation::Orientation::ID: break; case Transformation::Orientation::R1: break; case Transformation::Orientation::R2: From 9635cc331103c7b6025edf181e42cf91ae504194 Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 12 Jan 2022 13:41:54 +0000 Subject: [PATCH 8/9] lef: Fix MANUFACTURINGGRID order Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/LefExport.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crlcore/src/ccore/lefdef/LefExport.cpp b/crlcore/src/ccore/lefdef/LefExport.cpp index ac8b91dc..e2ee9c64 100644 --- a/crlcore/src/ccore/lefdef/LefExport.cpp +++ b/crlcore/src/ccore/lefdef/LefExport.cpp @@ -481,7 +481,13 @@ namespace { ); if ( status != 0 ) return driver->checkStatus(status); - return driver->checkStatus ( lefwEndUnits() ); + status = lefwEndUnits(); + + status = lefwManufacturingGrid ( LefDriver::toLefUnits(DbU::fromGrid(1.0)) ); + + if ( status != 0 ) return driver->checkStatus(status); + + return driver->checkStatus ( status ); } @@ -566,14 +572,7 @@ namespace { int LefDriver::_manufacturingGridCbk ( lefwCallbackType_e, lefiUserData udata ) { -#if 1 - // The driver puts it before UNITS, which seems to displease Cadence Encounter. - // So, as long as it doesn't prevent Encounter to works, disable it. - LefDriver* driver = (LefDriver*)udata; - return driver->checkStatus ( lefwManufacturingGrid ( LefDriver::toLefUnits(DbU::fromGrid(1.0)) ) ); -#else return 0; -#endif } From 6c66208e0cbd0316045fea01683e69c27e0745ad Mon Sep 17 00:00:00 2001 From: gatecat Date: Mon, 10 Jan 2022 19:30:59 +0000 Subject: [PATCH 9/9] def: Write route segments Signed-off-by: gatecat --- crlcore/src/ccore/lefdef/DefExport.cpp | 75 ++++++++++++++++++++++++++ lefdef/src/def/def/defwWriter.cpp | 2 +- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/crlcore/src/ccore/lefdef/DefExport.cpp b/crlcore/src/ccore/lefdef/DefExport.cpp index d5b9351c..e01a4e2b 100644 --- a/crlcore/src/ccore/lefdef/DefExport.cpp +++ b/crlcore/src/ccore/lefdef/DefExport.cpp @@ -32,6 +32,9 @@ #include "hurricane/Cell.h" #include "hurricane/Library.h" #include "hurricane/UpdateSession.h" +#include "hurricane/ViaLayer.h" +#include "hurricane/Rectilinear.h" + #include "crlcore/Utilities.h" #include "crlcore/ToolBox.h" #include "crlcore/RoutingGauge.h" @@ -108,6 +111,7 @@ namespace { inline unsigned int getFlags () const; inline int getStatus () const; int checkStatus ( int status ); + static int writeRouting ( Net*, bool special ); private: static int _designCbk ( defwCallbackType_e, defiUserData ); static int _designEndCbk ( defwCallbackType_e, defiUserData ); @@ -573,6 +577,73 @@ namespace { } + int DefDriver::writeRouting ( Net* net, bool special ) + { + int status = 0; + int i = 0; + for ( Component *component : net->getComponents() ) { + + std::string layer = component->getLayer() ? getString(component->getLayer()->getName()) : ""; + if (layer.size() >= 4 && layer.substr(layer.size() - 4) == ".pin") + continue; + if (layer.size() >= 6 && layer.substr(layer.size() - 6) == ".block") + continue; + + Segment *seg = dynamic_cast(component); + if (seg) { + status = (special ? defwSpecialNetPathStart : defwNetPathStart)((i++) ? "NEW" : "ROUTED"); + if (special) { + status = defwSpecialNetPathLayer(layer.c_str()); + status = defwSpecialNetPathWidth(int(toDefUnits(seg->getWidth()))); + } else { + status = defwNetPathLayer(layer.c_str(), 0, nullptr); + } + double x[2], y[2]; + x[0] = toDefUnits(seg->getSourceX()); + y[0] = toDefUnits(seg->getSourceY()); + x[1] = toDefUnits(seg->getTargetX()); + y[1] = toDefUnits(seg->getTargetY()); + status = (special ? defwSpecialNetPathPoint : defwNetPathPoint)(2, x, y); + } else { + Contact *contact = dynamic_cast(component); + if (contact) { + const ViaLayer *viaLayer = dynamic_cast(contact->getLayer()); + if (viaLayer) { + status = (special ? defwSpecialNetPathStart : defwNetPathStart)((i++) ? "NEW" : "ROUTED"); + if (special) + status = defwSpecialNetPathLayer(getString(viaLayer->getBottom()->getName()).c_str()); + else + status = defwNetPathLayer(getString(viaLayer->getBottom()->getName()).c_str(), 0, nullptr); + double x[1], y[1]; + x[0] = toDefUnits(contact->getX()); + y[0] = toDefUnits(contact->getY()); + status = (special ? defwSpecialNetPathPoint : defwNetPathPoint)(1, x, y); + status = (special ? defwSpecialNetPathVia : defwNetPathVia)(getString(viaLayer->getName()).c_str()); + } + } else { + Rectilinear *rl = dynamic_cast(component); + if (rl) { + Box box = rl->getBoundingBox(); + status = (special ? defwSpecialNetPathStart : defwNetPathStart)((i++) ? "NEW" : "ROUTED"); + if (special) + status = defwSpecialNetPathLayer(layer.c_str()); + else + status = defwNetPathLayer(layer.c_str(), 0, nullptr); + double x[1], y[1]; + x[0] = toDefUnits(box.getXMin()); + y[0] = toDefUnits(box.getYMin()); + status = (special ? defwSpecialNetPathPoint : defwNetPathPoint)(1, x, y); + defwNetPathRect(0, 0, toDefUnits(box.getWidth()), toDefUnits(box.getHeight())); + } + } + } + } + if (i > 0) + status = (special ? defwSpecialNetPathEnd : defwNetPathEnd)(); + return status; + } + + int DefDriver::_netCbk ( defwCallbackType_e, defiUserData udata ) { DefDriver* driver = (DefDriver*)udata; @@ -617,6 +688,7 @@ namespace { if ( status != 0 ) return driver->checkStatus(status); } + status = writeRouting(net, false); status = defwNetEndOneNet (); if ( status != 0 ) return driver->checkStatus(status); } @@ -658,6 +730,9 @@ namespace { status = defwSpecialNetUse ( netUse ); if ( status != 0 ) return driver->checkStatus(status); + status = writeRouting(*inet, true); + if ( status != 0 ) return driver->checkStatus(status); + status = defwSpecialNetEndOneNet (); if ( status != 0 ) return driver->checkStatus(status); } diff --git a/lefdef/src/def/def/defwWriter.cpp b/lefdef/src/def/def/defwWriter.cpp index e6276b5b..c0d9f57e 100644 --- a/lefdef/src/def/def/defwWriter.cpp +++ b/lefdef/src/def/def/defwWriter.cpp @@ -3127,7 +3127,7 @@ defwSpecialNetPathStart(const char *typ) if (strcmp(typ, "NEW") == 0) { if (defwState != DEFW_PATH) return DEFW_BAD_DATA; - fprintf(defwFile, " NEW"); + fprintf(defwFile, "\n NEW"); } else if (strcmp(typ, "SHIELD") == 0) { fprintf(defwFile, "\n + %s", typ); defwSpNetShield = 1;