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
|
@ -31,6 +31,7 @@ namespace CRL {
|
|||
public:
|
||||
static void reset ();
|
||||
static Hurricane::Library* load ( std::string fileName );
|
||||
static void setMergeLibrary ( Hurricane::Library* );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "hurricane/Contact.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Rectilinear.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Library.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
|
@ -71,6 +72,7 @@ namespace {
|
|||
|
||||
class LefParser {
|
||||
public:
|
||||
static void setMergeLibrary ( Library* );
|
||||
static DbU::Unit fromLefUnits ( int );
|
||||
static Layer* getLayer ( string );
|
||||
static void addLayer ( string, Layer* );
|
||||
|
@ -121,6 +123,7 @@ namespace {
|
|||
void _pinStdPostProcess ();
|
||||
void _pinPadPostProcess ();
|
||||
private:
|
||||
static Library* _mergeLibrary;
|
||||
string _file;
|
||||
string _libraryName;
|
||||
Library* _library;
|
||||
|
@ -174,11 +177,16 @@ namespace {
|
|||
inline void LefParser::clearPinSegments () { _pinSegments.clear(); }
|
||||
|
||||
|
||||
Library* LefParser::_mergeLibrary = nullptr;
|
||||
map<string,Layer*> LefParser::_layerLut;
|
||||
DbU::Unit LefParser::_coreSiteX = 0;
|
||||
DbU::Unit LefParser::_coreSiteY = 0;
|
||||
|
||||
|
||||
void LefParser::setMergeLibrary ( Library* library )
|
||||
{ _mergeLibrary = library; }
|
||||
|
||||
|
||||
void LefParser::reset ()
|
||||
{
|
||||
_layerLut.clear();
|
||||
|
@ -272,6 +280,11 @@ namespace {
|
|||
|
||||
Library* LefParser::createLibrary ()
|
||||
{
|
||||
if (_mergeLibrary) {
|
||||
_library = _mergeLibrary;
|
||||
return _library;
|
||||
}
|
||||
|
||||
DataBase* db = DataBase::getDB();
|
||||
Library* rootLibrary = db->getRootLibrary();
|
||||
if (not rootLibrary) rootLibrary = Library::create( db, "RootLibrary" );
|
||||
|
@ -499,6 +512,17 @@ namespace {
|
|||
}
|
||||
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;
|
||||
|
@ -647,6 +671,16 @@ namespace {
|
|||
//cerr << " | " << segment << endl;
|
||||
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) {
|
||||
// Ignore CLASS <site>. Deduced from segments positions.
|
||||
continue;
|
||||
|
@ -963,4 +997,12 @@ namespace CRL {
|
|||
}
|
||||
|
||||
|
||||
void LefImport::setMergeLibrary ( Library* library )
|
||||
{
|
||||
#if defined(HAVE_LEFDEF)
|
||||
LefParser::setMergeLibrary( library );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // End of CRL namespace.
|
||||
|
|
|
@ -43,6 +43,8 @@ namespace CRL {
|
|||
using Isobar::ParseTwoArg;
|
||||
using Isobar::__cs;
|
||||
using Isobar::PyLibrary_Link;
|
||||
using Isobar::PyTypeLibrary;
|
||||
using Isobar::PyLibrary;
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
@ -86,6 +88,27 @@ 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).
|
||||
|
||||
|
||||
|
@ -94,6 +117,8 @@ extern "C" {
|
|||
, "Load a complete Cadence LEF library." }
|
||||
, { "reset" , (PyCFunction)PyLefImport_reset , METH_NOARGS|METH_STATIC
|
||||
, "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 the associated hurricane object. The python object remains." }
|
||||
, {NULL, NULL, 0, NULL} /* sentinel */
|
||||
|
|
|
@ -304,3 +304,52 @@ def setupTSMC_c180_c4m ( checkToolkit=None, ndaTop=None ):
|
|||
|
||||
Yosys.setLiberty( liberty )
|
||||
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