separated oaTech opening and creation from design driving ... for mixed mode debug ...

This commit is contained in:
Jean-Manuel Caba 2010-09-18 11:57:37 +00:00
parent 1a33586cf9
commit 37d8084a6a
9 changed files with 266 additions and 162 deletions

View File

@ -10,8 +10,8 @@ using namespace Hurricane;
namespace CRL {
OADriver::OADriver(Cell* cell) : _cell(cell) {}
void OADriver::save(const std::string& filePath) {
CRL::OpenAccess::oaDriver(filePath, _cell);
void OADriver::save(const std::string& technoFilePath,const std::string& designFilePath) {
CRL::OpenAccess::oaDriver(technoFilePath,designFilePath, _cell);
}
OAParser::OAParser(const std::string& cellLibPath,const std::string& cellLibName,

View File

@ -15,7 +15,7 @@ namespace CRL {
Hurricane::Cell* _cell;
public:
OADriver(Hurricane::Cell*);
void save(const std::string& path);
void save(const std::string& technoFilePath,const std::string& designFilePath);
};
} // End of CRL namespace.

View File

@ -0,0 +1,11 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
#ifndef __MYASSERT_H__
#define __MYASSERT_H__
#include "hurricane/Error.h"
#undef assert
#define assert(cond) if (! (cond) ) throw Error("assertion failed : " + string( #cond ) )
#endif

View File

@ -1,5 +1,5 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-08-12 19:28:37" - OpenAccess.h
// Time-stamp: "2010-09-17 17:00:35" - OpenAccess.h
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
@ -24,9 +24,9 @@ namespace Hurricane {
namespace CRL {
class OpenAccess {
public:
static void oaDriver(const std::string& libPath, Hurricane::Cell* cell);
static void oaDriver(const std::string& technoPath, const std::string& designPath, Hurricane::Cell* cell);
static Hurricane::Cell* oaCellParser(const std::string& cellLibPath, const std::string& cellLibName, const std::string& cellName,
const std::string& techLibPath, const std::string& techLibName);
const std::string& techLibPath, const std::string& techLibName);
};
}//namespace CRL

View File

@ -1,5 +1,5 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-08-24 13:07:42" - OpenAccessCommon.h
// Time-stamp: "2010-09-18 13:38:28" - OpenAccessCommon.h
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
@ -14,12 +14,12 @@
#define __OPENACCESSCOMMON_H__
#include <iostream>
using namespace std;
#include <boost/filesystem/operations.hpp>
namespace bfs = boost::filesystem;
#ifdef HAVE_OPENACCESS
#include "PathsUtils.h"
#include "hurricane/Cell.h"
#include "hurricane/BasicLayer.h"
using namespace Hurricane;
@ -27,8 +27,8 @@ using namespace Hurricane;
#include "oa/oaDesignDB.h"
using namespace oa;
#undef assert
#define assert(cond) if (! (cond) ) throw Error("assertion failed : " + string( #cond ) )
#include "MyAssert.h"
//#define assert(cond)
namespace {
@ -137,32 +137,6 @@ namespace CRL_OA {
cerr << endl;
}
/**
@todo complete,verify ...
*/
static BasicLayer::Material::Code getBasicLayerTypeFromOAMaterial(const oaMaterial& material) {
switch(material) {
case oacNWellMaterial:
return BasicLayer::Material::nWell;
case oacPWellMaterial:
return BasicLayer::Material::pWell;
case oacNImplantMaterial:
return BasicLayer::Material::nImplant;
case oacPImplantMaterial:
return BasicLayer::Material::pImplant;
case oacPolyMaterial:
return BasicLayer::Material::poly;
case oacCutMaterial:
return BasicLayer::Material::cut;
case oacMetalMaterial:
case oacContactlessMetalMaterial:
return BasicLayer::Material::metal;
default:
return BasicLayer::Material::other;
}
}
/**
save and close design(s) stored in a map
*/
@ -191,13 +165,26 @@ namespace CRL_OA {
}
/**
handling realpath
*/
static void realPath(string& pathToChange){
if(bfs::path::default_name_check_writable())
bfs::path::default_name_check(bfs::portable_posix_name);
bfs::path resolvedPath = pathToChange;
pathToChange = system_complete(resolvedPath).string();
utility function to open a technology in OA format
*/
static pair<oaTech*,bool> openOATech(oaLib* techOAlib){
assert(techOAlib);
bool created = false;
cerr << "oaTech::find" << endl;
oaTech* theOATech = oaTech::find(techOAlib);
if(!theOATech){
if (oaTech::exists(techOAlib)){
cerr << "oaTech::open" << endl;
theOATech = oaTech::open(techOAlib,'a');
}
if(!theOATech){
cerr << "oaTech::create" << endl;
theOATech = oaTech::create(techOAlib);
created = true;
}
}
assert(techOAlib);
return make_pair<oaTech*,bool>(theOATech,created);
}
/**
@ -213,53 +200,7 @@ namespace CRL_OA {
}
/**
suppose the path has been resolved with system_complete
before calling this function and path are posix_name
then split the path in boos::filesystem::path corresponding of each dir
from most root parent to leaf dir
@see create_all_dirs
*/
static std::vector<bfs::path> split_in_dirs(const bfs::path& p){
string pstr(p.string());
register size_t len(pstr.length());
register char delim('/');
register size_t firstDelim=0;
register size_t secondDelim=1;
vector<bfs::path> dirs;
while(firstDelim < len){
while(secondDelim < len && pstr[secondDelim]!=delim)
secondDelim++;
string dir = pstr.substr(0,secondDelim);
if(dir.empty())
break;
dirs.push_back(bfs::path(dir));
firstDelim = secondDelim;
secondDelim++;
}
return dirs;
}
/**
work around for boost::filesystem::create_directories
missing in old boost versions like 1.33.1
and equivalent to recursivly creating directories
instead this is done iteratively.
*/
static void create_all_dirs(const bfs::path& p){
if(p.empty() || bfs::exists(p))
return;
std::vector<bfs::path> test;
test = split_in_dirs(p);
std::vector<bfs::path>::iterator it = test.begin();
for(;it != test.end();it++){
if(it->empty() || bfs::exists(*it))
continue;
bfs::create_directory(*it);
}
}
/**
open oaLib with the info gathered by libPath function
open oaLib with the info gathered by libInfos function
*/
static oaLib* openOALib(const pair<oaScalarName,string>& infos){
oaLib *lib = NULL;
@ -288,10 +229,11 @@ namespace CRL_OA {
}
/**
create cds.lib file in the path containong OA libs so Cadence (c) software could
open them
create cds.lib file in the path containing OA libs
so Cadence (c) software can open them
*/
static void createCDS(const pair<oaScalarName,string>& infos,const string& path){
static void createCDS(const pair<oaScalarName,string>& infos,
const string& path){
try{
cerr << "Overwriting cds.lib file begin " << endl;
string cdsPath = path + "/cds.lib";
@ -409,7 +351,7 @@ namespace CRL_OA {
}
return NULL;
}
};//struct oaCommon
};//struct oaFuncs
}//end CRL_OA namespace
#endif//HAVE_OPENACCESS

View File

@ -1,5 +1,5 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-08-26 17:35:32" - OpenAccessDriver.cpp
// Time-stamp: "2010-09-18 13:45:34" - OpenAccessDriver.cpp
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
@ -15,6 +15,7 @@
#include <iostream>
#include <algorithm>
#include <vector>
#include <memory>
using namespace std;
#include "hurricane/DataBase.h"
@ -43,6 +44,8 @@ using namespace Hurricane;
#include "OpenAccess.h"
#include "OpenAccessCommon.h"
#define VERBOSE
namespace {
#ifdef HAVE_OPENACCESS
using namespace CRL_OA;
@ -60,7 +63,8 @@ namespace {
typedef map<const Component*, oaRect*> Component2OARectMap;
typedef map<const Segment*, oaPathSeg*> Segment2OAPathSegMap;
string _path;
string _technoPath;
string _designPath;
oaTech* _oaTech;
Library2OALibMap _library2OALib;
Cell2OADesignMap _cell2OADesign4Netlist;
@ -80,9 +84,10 @@ namespace {
oaLayer* _layerWire;
DataBase* _db;
Technology* _technology;
public:
OADriver(const string& path) :
_path(path),
protected:
OADriver(const string& technoPath, const string& designPath) :
_technoPath(technoPath),
_designPath(designPath),
_oaTech(NULL),
_library2OALib(),
_cell2OADesign4Netlist(),
@ -102,20 +107,41 @@ namespace {
_layerWire(NULL),
_db(NULL),
_technology(NULL) {
cerr << "OADriver" << endl;
_db = DataBase::getDB();
if (!_db) {
if (!_db)
throw Error("no database");
}
_technology = _db->getTechnology();
if (!_technology) {
if (!_technology)
throw Error("no technology");
}
oaFuncs::realPath(_path);
cerr << "realpath: " << _path << endl;
realPath(_technoPath);
realPath(_designPath);
cerr << "techno realpath: " << _technoPath << endl;
cerr << "design realpath: " << _designPath << endl;
}
public:
static OADriver* create(const string& technoPath, const string& designPath) {
OADriver* oaDriver = new OADriver(technoPath,designPath);
// load previously converted or existing tech in OA format
oaDriver->getOATech();
return oaDriver;
}
oaTech* getOATech() {
assert(_oaTech);
return _oaTech;
}
~OADriver() {
cerr << "~OADriver" << endl;
#ifdef VERBOSE
cerr << "SAVING ALL" << endl;
#endif
_oaTech->save();
_oaTech->close();
oaFuncs::saveOADesignsInMap(_cell2OADesign4Netlist);
@ -132,42 +158,55 @@ namespace {
oaLib* lib = it->second;
lib->close();
}
_path.clear();
_technoPath.clear();
_designPath.clear();
#ifdef VERBOSE
cerr << "ALL SAVED" << endl;
#endif
}
oaTech* loadOATech(const string& path) {
oaLib* lib = NULL;
oaTech* tech = NULL;
return tech;
}
/**
create a oaLib from a Library
*/
oaLib* toOALib(const Library* library, bool recursive=false) {
cerr << "toOALib" << endl;
oaLib* toOALib(const Library* library, const string& path,bool recursive=false) {
assert(library);
Library2OALibMap::iterator it = _library2OALib.find(library);
if (it != _library2OALib.end())
return it->second;
cerr << "toOALib" << endl;
// 1) create or open library
cerr << "lib path : " << _path << endl;
pair<oaScalarName,string> infos = oaFuncs::libInfos(_path,
#ifdef VERBOSE
cerr << "lib path : " << path << endl;
#endif
pair<oaScalarName,string> infos = oaFuncs::libInfos(path,
getString(library->getName()));
oaLib *lib = oaFuncs::openOALib(infos);
_library2OALib[library] = lib;
if(recursive){
// 2) for each cell convert them too : if it's a standard cell library for example
for_each_cell(c ,library->getCells()){
toOACell(c);
end_for;
if(_oaTech){
for_each_cell(c ,library->getCells()){
toOACell(_oaTech, c);
end_for;
}
}
// 3) also convert each contained library if any
for_each_library(l ,library->getLibraries()){
toOALib(l);
toOALib(l,path,recursive);
end_for;
}
}
// 4) create, update library list file
oaFuncs::createCDS(infos,_path);
oaFuncs::createCDS(infos,path);
infos.second.clear();
return lib;
@ -179,23 +218,32 @@ namespace {
*/
int generateLayerID(const BasicLayer* bLayer){
// the layer number is unique to a particular layer
cerr << "generateLayerID -> ";
cerr << "generateLayerID";
#ifdef VERBOSE
cerr << " -> ";
#endif
int numLayer = _layerID;
if(bLayer){
numLayer = bLayer->getExtractNumber();
if(_layerIDS.find(numLayer) == _layerIDS.end()){
#ifdef VERBOSE
cerr << "getExtractNumber " << numLayer << endl;
#endif
_layerIDS.insert(numLayer);
return numLayer;
}
}
cerr << " while(...) ";
#ifdef VERBOSE
cerr << "while(...) ";
#endif
set<int>::iterator it;
while((it = _layerIDS.find(_layerID)) != _layerIDS.end()){
numLayer = ++_layerID;
}
#ifdef VERBOSE
cerr << numLayer << endl;
#endif
_layerIDS.insert(numLayer);
return numLayer;
}
@ -347,7 +395,7 @@ namespace {
aOALayer->getNumber(),
(oaLayerConstraintDef*) def);
}
return aOALayer;
}
@ -359,38 +407,30 @@ namespace {
@todo complete with technology info for layers
@see toOALib
*/
oaTech* toOATech(const Technology* technology,const Library* lib) {
oaTech* toOATech(const Technology* technology,
const Library* lib,
const string& technoPath) {
cerr << "createOATechForTechnology" << endl;
assert(technology);
// 1) get or create Library for the techno
assert(lib);
oaLib* techOAlib = toOALib(lib);
oaLib* techOAlib = toOALib(lib,technoPath);
assert(techOAlib);
// 2) get or create oaTech container
bool created = false;
cerr << "oaTech::find" << endl;
oaTech* theOATech = oaTech::find(techOAlib);
if(!theOATech){
if (oaTech::exists(techOAlib)){
cerr << "oaTech::open" << endl;
theOATech = oaTech::open(techOAlib,'a');
}
if(!theOATech){
cerr << "oaTech::create" << endl;
theOATech = oaTech::create(techOAlib);
created = true;
}
}
assert(techOAlib);
pair<oaTech*,bool> techPair = oaFuncs::openOATech(techOAlib);
oaTech* theOATech = techPair.first;
bool created = techPair.second;
assert(theOATech);
if(created){
theOATech->setDefaultManufacturingGrid(10);
theOATech->setDBUPerUU(oaViewType::get(oacMaskLayout), 2000);
//create and add foundry constraint group
//for General manufacturing rules
//and add oaSimpleConstraintType too
//create and add foundry constraint group for General manufacturing rules
//and add oaSimpleConstraintType too
assert(theOATech);
//add the constraint group for oa2lef
theOATech->getDefaultConstraintGroup();
oaConstraintGroup *cgFoundry = theOATech->getFoundryRules();
@ -496,7 +536,7 @@ namespace {
// 1) get the master cell for the instance
Cell* masterCell = instance->getMasterCell();
assert(masterCell);
oaDesign* masterDesign = toOADesign(masterCell);
oaDesign* masterDesign = toOADesign(_oaTech,masterCell);
assert(masterDesign);
oaNativeNS ns;
@ -555,6 +595,7 @@ namespace {
return oaName(scN);
}
/**
convert to OAPoint
*/
@ -820,7 +861,7 @@ namespace {
// 1) get the lib containing the cell
oaNativeNS ns;
oaLib* lib = toOALib(cell->getLibrary());
oaLib* lib = toOALib(cell->getLibrary(),_designPath);
assert(lib);
// 2) create a netlist CellView of the cell
@ -857,7 +898,7 @@ namespace {
return it->second;
}
oaNativeNS ns;
oaLib* lib = toOALib(cell->getLibrary());
oaLib* lib = toOALib(cell->getLibrary(),_designPath);
assert(lib);
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "symbolic");
@ -895,7 +936,7 @@ namespace {
return it->second;
oaNativeNS ns;
oaLib* lib = toOALib(cell->getLibrary());
oaLib* lib = toOALib(cell->getLibrary(),_designPath);
assert(lib);
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "schematic");
@ -933,7 +974,7 @@ namespace {
}
oaNativeNS ns;
oaLib* lib = toOALib(cell->getLibrary());
oaLib* lib = toOALib(cell->getLibrary(), _designPath);
assert(lib);
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "layout");
@ -988,12 +1029,13 @@ namespace {
oaBox boundingBox = toOABox(bBox);
topBlock->getBBox(boundingBox);
}
//tests
oaUInt4 count = 0;
oaIter<oaLPPHeader> headers(designCellView->getTopBlock()->getLPPHeaders());
while (oaLPPHeader* lppHeader = headers.getNext()) {
cout << "Layer Purpose Pair " << ++count << endl;
oaLayerNum layerNum = lppHeader->getLayerNum();
oaPurposeNum purpNum = lppHeader->getPurposeNum();
cout << "\t Layer = " << layerNum << endl;
@ -1006,13 +1048,16 @@ namespace {
/**
Convert a Cell to OA designs ...
*/
oaDesign* toOADesign(const Cell* cell) {
oaDesign* toOADesign(oaTech* tech,const Cell* cell) {
cerr << "toOADesign " << cell << endl;
assert(cell);
assert(tech);
_oaTech = tech;
#if 0
// 1) get technology
if(!_oaTech)
_oaTech = toOATech(_technology,cell->getLibrary());
#endif
// 2) create OA structure ...
oaDesign* layoutView = addLayout(cell);
@ -1062,12 +1107,12 @@ namespace {
return cell;
}
oaCell* toOACell(const Cell* cell) {
oaCell* toOACell(oaTech* tech, const Cell* cell) {
Cell2OACellMap::iterator it = _cell2OAcell.find(cell);
if (it != _cell2OAcell.end())
return it->second;
oaCell* c1 = toOACell( toOADesign(cell) );
oaCell* c1 = toOACell( toOADesign(tech, cell) );
_cell2OAcell[cell] = c1;
return c1;
@ -1077,7 +1122,7 @@ namespace {
}//namespace CRL_OA
namespace CRL {
void OpenAccess::oaDriver(const string& path, Cell* cell) {
void OpenAccess::oaDriver(const string& technoPath,const string& designPath, Cell* cell) {
cerr << "oaDriver" << endl;
#ifdef HAVE_OPENACCESS
oaCell* convertedCell = NULL;
@ -1085,18 +1130,23 @@ namespace CRL {
cell->materialize();
//for the moment a driver for hurricaneAMS
//save the Cell only and all used Cell
cerr << "Saving " << cell << " in " << path << endl;
cerr << "Saving design " << cell << " in " << designPath << endl;
cerr << "Using techno from " << technoPath << endl;
try {
oaDesignInit(oacAPIMajorRevNumber,
oacAPIMinorRevNumber,
oacDataModelRevNumber);
OADriver oaDriver(path);
convertedCell = oaDriver.toOACell(cell);
auto_ptr<OADriver> oaDriver(OADriver::create(technoPath, designPath));
oaTech* tech = NULL;
tech = oaDriver->getOATech();
assert(tech);
convertedCell = oaDriver->toOACell(tech,cell);
}catch (oaException &e) {
cerr << "OA::ERROR => " << e.getMsg() << endl;
exit(1);
}catch(std::exception& e){
}catch(std::exception& e) {
cerr << "STD::ERROR => " << e.what() << endl;
exit(2);
}

View File

@ -1,5 +1,5 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-08-13 00:11:06" - OpenAccessParser.cpp
// Time-stamp: "2010-09-18 13:28:46" - OpenAccessParser.cpp
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
@ -71,6 +71,31 @@ namespace {
}
}
/**
@todo complete,verify ...
*/
static BasicLayer::Material::Code fromOAMaterial(const oaMaterial& material) {
switch(material) {
case oacNWellMaterial:
return BasicLayer::Material::nWell;
case oacPWellMaterial:
return BasicLayer::Material::pWell;
case oacNImplantMaterial:
return BasicLayer::Material::nImplant;
case oacPImplantMaterial:
return BasicLayer::Material::pImplant;
case oacPolyMaterial:
return BasicLayer::Material::poly;
case oacCutMaterial:
return BasicLayer::Material::cut;
case oacMetalMaterial:
case oacContactlessMetalMaterial:
return BasicLayer::Material::metal;
default:
return BasicLayer::Material::other;
}
}
Cell* getCell(const string& cellNameStr) {
DataBase* db = DataBase::getDB();
if (!db || !db->getRootLibrary() ) {
@ -107,7 +132,7 @@ namespace {
Library* library = nit->second;
string libPath = libPathStr;
oaFuncs::realPath(libPath);
realPath(libPath);
oaLib* oaLibrary = NULL;
try {
@ -120,7 +145,7 @@ namespace {
}
cerr << "TITI" << endl;
oaTechnology2Technology(oaLibrary);
fromOATech(oaLibrary);
//create Hurricane library
DataBase* db = DataBase::getDB();
@ -294,7 +319,7 @@ namespace {
/**
heart of the parser algorithm
*/
void oaTechnology2Technology(oaLib* oaLibrary) {
void fromOATech(oaLib* oaLibrary) {
assert(oaLibrary);
try {
oaTech* tech = oaTech::open(oaLibrary);

View File

@ -0,0 +1,76 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-09-17 17:22:49" - PathsUtils.h
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
// | =============================================================== |
// | Author : Jean-Manuel Caba |
// | E-mail : Jean-Manuel.Caba@asim.lip6.fr |
// x-----------------------------------------------------------------x
#ifndef __PATHSUTILS_H__
#define __PATHSUTILS_H__
#include <iostream>
using namespace std;
#include <boost/filesystem/operations.hpp>
namespace bfs = boost::filesystem;
/**
handling realpath
*/
static void realPath(string& pathToChange){
if(bfs::path::default_name_check_writable())
bfs::path::default_name_check(bfs::portable_posix_name);
bfs::path resolvedPath = pathToChange;
pathToChange = system_complete(resolvedPath).string();
}
/**
suppose the path has been resolved with system_complete
before calling this function and path are posix_name
then split the path in boos::filesystem::path corresponding of each dir
from most root parent to leaf dir
@see create_all_dirs
*/
static std::vector<bfs::path> split_in_dirs(const bfs::path& p){
string pstr(p.string());
register size_t len(pstr.length());
register char delim('/');
register size_t firstDelim=0;
register size_t secondDelim=1;
vector<bfs::path> dirs;
while(firstDelim < len){
while(secondDelim < len && pstr[secondDelim]!=delim)
secondDelim++;
string dir = pstr.substr(0,secondDelim);
if(dir.empty())
break;
dirs.push_back(bfs::path(dir));
firstDelim = secondDelim;
secondDelim++;
}
return dirs;
}
/**
work around for boost::filesystem::create_directories
missing in old boost versions like 1.33.1
and equivalent to recursivly creating directories
instead this is done iteratively.
*/
static void create_all_dirs(const bfs::path& p){
if(p.empty() || bfs::exists(p))
return;
std::vector<bfs::path> test;
test = split_in_dirs(p);
std::vector<bfs::path>::iterator it = test.begin();
for(;it != test.end();it++){
if(it->empty() || bfs::exists(*it))
continue;
bfs::create_directory(*it);
}
}
#endif//__PATHSUTILS_H__

View File

@ -40,4 +40,4 @@ export OA_PLUGIN_PATH=$OPENACCESS_TOP/data
# note that $TEMP is /dsk/l1/misc/$(USER) directory
export OA_INCLUDE_DIR=$TEMP/OA_HEADER
#si on utilise OA de si2 on aura
#export OPENACCESS_INCLUDE=$OPENACCESS_TOP/include
#export OA_INCLUDE_DIR=$OPENACCESS_TOP/include