Added support for GF180MCU, part 1.
* New: In LefImport::LefParser, add support for LEF Polygons that are translated into Hurricane Rectilinears. * Change: In LefImport::setMergeLibrary(), the default behavior for the LEF parser is to create a new separate library under LEF/<lib_name> for each file. But if the various cells are put each one in it's own cell, this is suitable. So we can now set a library beforehand into which they will be all put. * New: in CRL/technos.node180.gf180mcu, configuration files for the GF180MCU open PDK. * New: in cumulus/designflow.technos, added a setupGF180MCU_GF() to initialize the GF PDK.
This commit is contained in:
parent
06ea3d6e09
commit
76e9da0b64
|
@ -29,8 +29,9 @@ namespace CRL {
|
||||||
|
|
||||||
class LefImport {
|
class LefImport {
|
||||||
public:
|
public:
|
||||||
static void reset ();
|
static void reset ();
|
||||||
static Hurricane::Library* load ( std::string fileName );
|
static Hurricane::Library* load ( std::string fileName );
|
||||||
|
static void setMergeLibrary ( Hurricane::Library* );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "hurricane/Contact.h"
|
#include "hurricane/Contact.h"
|
||||||
#include "hurricane/Horizontal.h"
|
#include "hurricane/Horizontal.h"
|
||||||
#include "hurricane/Vertical.h"
|
#include "hurricane/Vertical.h"
|
||||||
|
#include "hurricane/Rectilinear.h"
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
#include "hurricane/Library.h"
|
#include "hurricane/Library.h"
|
||||||
#include "hurricane/UpdateSession.h"
|
#include "hurricane/UpdateSession.h"
|
||||||
|
@ -71,6 +72,7 @@ namespace {
|
||||||
|
|
||||||
class LefParser {
|
class LefParser {
|
||||||
public:
|
public:
|
||||||
|
static void setMergeLibrary ( Library* );
|
||||||
static DbU::Unit fromLefUnits ( int );
|
static DbU::Unit fromLefUnits ( int );
|
||||||
static Layer* getLayer ( string );
|
static Layer* getLayer ( string );
|
||||||
static void addLayer ( string, Layer* );
|
static void addLayer ( string, Layer* );
|
||||||
|
@ -121,6 +123,7 @@ namespace {
|
||||||
void _pinStdPostProcess ();
|
void _pinStdPostProcess ();
|
||||||
void _pinPadPostProcess ();
|
void _pinPadPostProcess ();
|
||||||
private:
|
private:
|
||||||
|
static Library* _mergeLibrary;
|
||||||
string _file;
|
string _file;
|
||||||
string _libraryName;
|
string _libraryName;
|
||||||
Library* _library;
|
Library* _library;
|
||||||
|
@ -174,11 +177,16 @@ namespace {
|
||||||
inline void LefParser::clearPinSegments () { _pinSegments.clear(); }
|
inline void LefParser::clearPinSegments () { _pinSegments.clear(); }
|
||||||
|
|
||||||
|
|
||||||
|
Library* LefParser::_mergeLibrary = nullptr;
|
||||||
map<string,Layer*> LefParser::_layerLut;
|
map<string,Layer*> LefParser::_layerLut;
|
||||||
DbU::Unit LefParser::_coreSiteX = 0;
|
DbU::Unit LefParser::_coreSiteX = 0;
|
||||||
DbU::Unit LefParser::_coreSiteY = 0;
|
DbU::Unit LefParser::_coreSiteY = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void LefParser::setMergeLibrary ( Library* library )
|
||||||
|
{ _mergeLibrary = library; }
|
||||||
|
|
||||||
|
|
||||||
void LefParser::reset ()
|
void LefParser::reset ()
|
||||||
{
|
{
|
||||||
_layerLut.clear();
|
_layerLut.clear();
|
||||||
|
@ -272,6 +280,11 @@ namespace {
|
||||||
|
|
||||||
Library* LefParser::createLibrary ()
|
Library* LefParser::createLibrary ()
|
||||||
{
|
{
|
||||||
|
if (_mergeLibrary) {
|
||||||
|
_library = _mergeLibrary;
|
||||||
|
return _library;
|
||||||
|
}
|
||||||
|
|
||||||
DataBase* db = DataBase::getDB();
|
DataBase* db = DataBase::getDB();
|
||||||
Library* rootLibrary = db->getRootLibrary();
|
Library* rootLibrary = db->getRootLibrary();
|
||||||
if (not rootLibrary) rootLibrary = Library::create( db, "RootLibrary" );
|
if (not rootLibrary) rootLibrary = Library::create( db, "RootLibrary" );
|
||||||
|
@ -499,6 +512,17 @@ namespace {
|
||||||
}
|
}
|
||||||
cdebug_log(100,0) << "| " << segment << endl;
|
cdebug_log(100,0) << "| " << segment << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (geoms->itemType(igeom) == lefiGeomPolygonE) {
|
||||||
|
lefiGeomPolygon* polygon = geoms->getPolygon(igeom);
|
||||||
|
vector<Point> points;
|
||||||
|
for ( int ipoint=0 ; ipoint<polygon->numPoints ; ++ipoint ) {
|
||||||
|
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint])
|
||||||
|
, parser->fromUnitsMicrons(polygon->y[ipoint]) ));
|
||||||
|
}
|
||||||
|
Rectilinear::create( blockageNet, blockageLayer, points );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -647,6 +671,16 @@ namespace {
|
||||||
//cerr << " | " << segment << endl;
|
//cerr << " | " << segment << endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (geoms->itemType(igeom) == lefiGeomPolygonE) {
|
||||||
|
lefiGeomPolygon* polygon = geoms->getPolygon(igeom);
|
||||||
|
vector<Point> points;
|
||||||
|
for ( int ipoint=0 ; ipoint<polygon->numPoints ; ++ipoint ) {
|
||||||
|
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint])
|
||||||
|
, parser->fromUnitsMicrons(polygon->y[ipoint]) ));
|
||||||
|
}
|
||||||
|
Rectilinear::create( net, layer, points );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (geoms->itemType(igeom) == lefiGeomClassE) {
|
if (geoms->itemType(igeom) == lefiGeomClassE) {
|
||||||
// Ignore CLASS <site>. Deduced from segments positions.
|
// Ignore CLASS <site>. Deduced from segments positions.
|
||||||
continue;
|
continue;
|
||||||
|
@ -963,4 +997,12 @@ namespace CRL {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LefImport::setMergeLibrary ( Library* library )
|
||||||
|
{
|
||||||
|
#if defined(HAVE_LEFDEF)
|
||||||
|
LefParser::setMergeLibrary( library );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // End of CRL namespace.
|
} // End of CRL namespace.
|
||||||
|
|
|
@ -43,6 +43,8 @@ namespace CRL {
|
||||||
using Isobar::ParseTwoArg;
|
using Isobar::ParseTwoArg;
|
||||||
using Isobar::__cs;
|
using Isobar::__cs;
|
||||||
using Isobar::PyLibrary_Link;
|
using Isobar::PyLibrary_Link;
|
||||||
|
using Isobar::PyTypeLibrary;
|
||||||
|
using Isobar::PyLibrary;
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -86,14 +88,37 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject* PyLefImport_setMergeLibrary ( PyObject*, PyObject* args )
|
||||||
|
{
|
||||||
|
cdebug_log(30,0) << "PyLefImport_setMergeLibrary()" << endl;
|
||||||
|
HTRY
|
||||||
|
PyObject* pyLibrary = NULL;
|
||||||
|
if (PyArg_ParseTuple( args, "O:LefImport.setMergeLibrary", &pyLibrary )) {
|
||||||
|
if (IsPyLibrary(pyLibrary)) {
|
||||||
|
LefImport::setMergeLibrary( PYLIBRARY_O(pyLibrary) );
|
||||||
|
} else {
|
||||||
|
PyErr_SetString( ConstructorError, "LefImport.setMergeLibrary(): Bad parameter type (not a Library)." );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PyErr_SetString( ConstructorError, "LefImport.setMergeLibrary(): Bad number of parameters." );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
HCATCH
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Standart Destroy (Attribute).
|
// Standart Destroy (Attribute).
|
||||||
|
|
||||||
|
|
||||||
PyMethodDef PyLefImport_Methods[] =
|
PyMethodDef PyLefImport_Methods[] =
|
||||||
{ { "load" , (PyCFunction)PyLefImport_load , METH_VARARGS|METH_STATIC
|
{ { "load" , (PyCFunction)PyLefImport_load , METH_VARARGS|METH_STATIC
|
||||||
, "Load a complete Cadence LEF library." }
|
, "Load a complete Cadence LEF library." }
|
||||||
, { "reset" , (PyCFunction)PyLefImport_reset , METH_NOARGS|METH_STATIC
|
, { "reset" , (PyCFunction)PyLefImport_reset , METH_NOARGS|METH_STATIC
|
||||||
, "Reset the Cadence LEF parser (clear technology)." }
|
, "Reset the Cadence LEF parser (clear technology)." }
|
||||||
|
, { "setMergeLibrary" , (PyCFunction)PyLefImport_setMergeLibrary, METH_VARARGS|METH_STATIC
|
||||||
|
, "Merge into this library instead of creating a new one." }
|
||||||
//, { "destroy" , (PyCFunction)PyLefImport_destroy , METH_VARARGS
|
//, { "destroy" , (PyCFunction)PyLefImport_destroy , METH_VARARGS
|
||||||
// , "Destroy the associated hurricane object. The python object remains." }
|
// , "Destroy the associated hurricane object. The python object remains." }
|
||||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||||
|
|
|
@ -304,3 +304,52 @@ def setupTSMC_c180_c4m ( checkToolkit=None, ndaTop=None ):
|
||||||
|
|
||||||
Yosys.setLiberty( liberty )
|
Yosys.setLiberty( liberty )
|
||||||
ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix()
|
ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix()
|
||||||
|
|
||||||
|
|
||||||
|
def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None ):
|
||||||
|
from .. import Cfg
|
||||||
|
from .. import Viewer
|
||||||
|
from .. import CRL
|
||||||
|
from ..helpers import setNdaTopDir, overlay, l, u, n
|
||||||
|
from .yosys import Yosys
|
||||||
|
|
||||||
|
if isinstance(pdkTop,str):
|
||||||
|
pdkTop = Path( pdkTop )
|
||||||
|
if not pdkTop:
|
||||||
|
print( '[ERROR] technos.setupGF180MCU_GF(): pdkTop directory has *not* been set.' )
|
||||||
|
if not pdkTop.is_dir():
|
||||||
|
print( '[ERROR] technos.setupSky130_c4m(): pdkTop directory do *not* exists:' )
|
||||||
|
print( ' "{}"'.format(pdkTop.as_posix()) )
|
||||||
|
|
||||||
|
Where( checkToolkit )
|
||||||
|
|
||||||
|
cellsTop = pdkTop / 'libraries' / 'gf180mcu_fd_sc_mcu9t5v0' / 'latest' / 'cells'
|
||||||
|
#liberty = pdkTop / 'libraries' / 'gf180mcu_fd_sc_mcu9t5v0' / 'latest' / 'liberty' / 'gf180mcu_fd_sc_mcu9t5v0__tt_025C_5v00.lib'
|
||||||
|
liberty = pdkTop / 'FULL.lib'
|
||||||
|
|
||||||
|
from coriolis.technos.node180.gf180mcu import techno
|
||||||
|
from coriolis.technos.node180.gf180mcu import mcu9t5v0
|
||||||
|
techno.setup()
|
||||||
|
mcu9t5v0.setup( cellsTop )
|
||||||
|
|
||||||
|
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
|
||||||
|
cfg.misc.catchCore = False
|
||||||
|
cfg.misc.minTraceLevel = 12300
|
||||||
|
cfg.misc.maxTraceLevel = 12400
|
||||||
|
cfg.misc.info = False
|
||||||
|
cfg.misc.paranoid = False
|
||||||
|
cfg.misc.bug = False
|
||||||
|
cfg.misc.logMode = True
|
||||||
|
cfg.misc.verboseLevel1 = False
|
||||||
|
cfg.misc.verboseLevel2 = False
|
||||||
|
cfg.etesian.graphics = 2
|
||||||
|
cfg.anabatic.topRoutingLayer = 'm4'
|
||||||
|
cfg.katana.eventsLimit = 4000000
|
||||||
|
af = CRL.AllianceFramework.get()
|
||||||
|
#lg5 = af.getRoutingGauge( 'mcu9t' ).getLayerGauge( 5 )
|
||||||
|
#lg5.setType( CRL.RoutingLayerGauge.PowerSupply )
|
||||||
|
env = af.getEnvironment()
|
||||||
|
env.setCLOCK( '^sys_clk$|^ck|^jtag_tck$' )
|
||||||
|
|
||||||
|
Yosys.setLiberty( liberty )
|
||||||
|
ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix()
|
||||||
|
|
Loading…
Reference in New Issue