diff --git a/crlcore/src/ccore/openaccess/OpenAccess.h b/crlcore/src/ccore/openaccess/OpenAccess.h index 23a88b69..a942eeb5 100644 --- a/crlcore/src/ccore/openaccess/OpenAccess.h +++ b/crlcore/src/ccore/openaccess/OpenAccess.h @@ -1,5 +1,5 @@ // -*-compile-command:"cd ../../../../.. && make"-*- -// Time-stamp: "2010-07-26 16:16:41" - OpenAccess.h +// Time-stamp: "2010-08-05 20:13:03" - OpenAccess.h // x-----------------------------------------------------------------x // | This file is part of the hurricaneAMS Software. | // | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved | @@ -21,22 +21,12 @@ namespace Hurricane { class Cell; } -#ifdef HAVE_OPENACCESS -#include "oa/oaDesignDB.h" -using namespace oa; -#else -namespace oa { - class oaCell; - class oaLib; -} -#endif - namespace CRL { class OpenAccess { public: - static Hurricane::Cell* oaCellParser(oa::oaCell* cell); - static Hurricane::Library* oaLibParser(oa::oaLib* lib); - static oa::oaCell* oaDriver(const std::string& libPath, Hurricane::Cell* cell); + static void oaDriver(const std::string& libPath, Hurricane::Cell* cell); + static Hurricane::Cell* oaCellParser(const std::string& libPath, + const std::string& libName, const std::string& cellName); }; }//namespace CRL diff --git a/crlcore/src/ccore/openaccess/OpenAccessCommon.h b/crlcore/src/ccore/openaccess/OpenAccessCommon.h index f28c3f2d..9f7e6fa2 100644 --- a/crlcore/src/ccore/openaccess/OpenAccessCommon.h +++ b/crlcore/src/ccore/openaccess/OpenAccessCommon.h @@ -1,5 +1,5 @@ // -*-compile-command:"cd ../../../../.. && make"-*- -// Time-stamp: "2010-08-05 18:18:32" - OpenAccessCommon.h +// Time-stamp: "2010-08-06 01:21:19" - OpenAccessCommon.h // x-----------------------------------------------------------------x // | This file is part of the hurricaneAMS Software. | // | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved | @@ -32,838 +32,539 @@ using namespace oa; //#define assert(cond) namespace { + //multiplicator of BoundingBOX coordinates + const int convertFactor = 1; + const Name OACellLibrariesName("OACellLibraries"); + const Name OADesignLibrariesName("OADesignLibraries"); +} - /** - giving a oaDesign pointer that should be not NULL - return the oaString representing its name - */ - inline oaString getDesignName(oaDesign* design) { - assert(design); - oaNativeNS ns; - oaString libName, cellName, viewName; - design->getLibName(ns, libName); - design->getCellName(ns, cellName); - design->getViewName(ns, viewName); - oaString designName = "<" + libName + "," + cellName + "," + viewName + ">"; - return designName; - } - - /** - giving a oaBlock - print the connectivity, mainly used for debug purpose ... - @todo remove when not needed anymore - */ - inline void printBlockTerms(oaBlock* block) { - assert(block); - oaNativeNS ns; - oaDesign* design = block->getDesign(); - cerr << " o Printing " << getDesignName(design) << " terms" << endl; - oaIter termIter(block->getTerms()); - while (oaTerm* term = termIter.getNext()) { - oaString termName; - term->getName(ns, termName); - cerr << " - " << termName << endl; +namespace CRL_OA { + struct oaFuncs { + //for namespaces in Hurricane + /** + get a Hurricane::Library by Name in a Hurricane DB + */ + static Library* findLibraryByNameInLibrary(const Library* rootLibrary, const Name& libraryName) { + for_each_library(library, rootLibrary->getLibraries()) { + if (library->getName() == libraryName) { + return library; + } + Library* foundLibrary = findLibraryByNameInLibrary(library, libraryName); + if (foundLibrary) { + return foundLibrary; + } + end_for; + } + return NULL; } - cerr << endl; - } - /** - Convert material from Hurricane to OA ... - @todo verify - */ - inline oaMaterial getOAMaterial(const BasicLayer::Material& material) { - switch ( material.getCode() ) { - case BasicLayer::Material::nWell: return oacNWellMaterial; - case BasicLayer::Material::pWell: return oacPWellMaterial; - case BasicLayer::Material::nImplant: return oacNImplantMaterial; - case BasicLayer::Material::pImplant: return oacPImplantMaterial; - case BasicLayer::Material::active: return oacOtherMaterial;//is it OK? - case BasicLayer::Material::poly: return oacPolyMaterial; - case BasicLayer::Material::cut: return oacCutMaterial; - case BasicLayer::Material::metal: return oacMetalMaterial; - case BasicLayer::Material::blockage: - //there is no blockage type but a specific oaLayerBlockage class - return oacOtherMaterial; - case BasicLayer::Material::other: return oacOtherMaterial; - default: - throw Error("Unrecognized material"); + /** + get a Hurricane::Library by Name in a Hurricane DB + */ + static Library* findLibraryByNameInDB(const DataBase* db, const Name& libraryName) { + Library* rootLibrary = db->getRootLibrary(); + if (rootLibrary->getName() == libraryName) { + return rootLibrary; + } + return findLibraryByNameInLibrary(rootLibrary, libraryName); } - } - /** - @todo complete,verify ... - */ - inline BasicLayer::Material::Code oaMaterialToBasicLayerType(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; + /** + populate the set passed as parameter with all cells of a Hurricane::Library + */ + static void getAllCells(Library* rootLibrary, set& cellSet) { + for_each_cell(cell, rootLibrary->getCells()) { + cellSet.insert(cell); + end_for; + } + for_each_library(library, rootLibrary->getLibraries()) { + getAllCells(library, cellSet); + end_for; + } } - } - /** - Convertion helper for Net convertion ... - @todo verify - */ - inline oaTermType getOATermType(const Net::Direction& direction) { - switch (direction) { - case Net::Direction::IN: - return oacInputTermType; - case Net::Direction::OUT: - return oacOutputTermType; - case Net::Direction::INOUT: - return oacInputOutputTermType; - case Net::Direction::TRISTATE: - return oacTristateTermType; - case Net::Direction::UNDEFINED: - return oacUnusedTermType;// is it OK ? - default: - throw Error("Unrecognized direction"); + /** + find a cell by name in a Hurricane::Library + */ + static Cell* findCellInLibraries(const Library* rootLibrary, const Name& cellName) { + for_each_cell(cell, rootLibrary->getCells()) { + if (cell->getName() == cellName) { + return cell; + } + end_for; + } + for_each_library(library, rootLibrary->getLibraries()) { + Cell* cell = findCellInLibraries(library, cellName); + if (cell) { + return cell; + } + end_for; + } + return NULL; } - } - /** - Convertion helper for Net convertion ... - @todo verify - */ - inline oaSigType getOASigType(const Net::Type& type) { - switch (type.getCode()) { - case Net::Type::LOGICAL: - return oacSignalSigType; - case Net::Type::CLOCK: - return oacClockSigType; - case Net::Type::POWER: - return oacPowerSigType; - case Net::Type::GROUND: - return oacGroundSigType; - case Net::Type::UNDEFINED: - return oacAnalogSigType;// is it OK ? - default: - throw Error("Unrecognized net type"); + /** + giving a oaDesign pointer that should be not NULL + return the oaString representing its name + */ + static oaString getOADesignName(oaDesign* design) { + assert(design); + oaNativeNS ns; + oaString libName, cellName, viewName; + design->getLibName(ns, libName); + design->getCellName(ns, cellName); + design->getViewName(ns, viewName); + oaString designName = "<" + libName + "," + cellName + "," + viewName + ">"; + return designName; } - } - /** - Convertion helper ... - */ - inline oaOrient getOAOrientFromOrientation(const Transformation::Orientation& orientation) { - switch (orientation) { - case Transformation::Orientation::ID: - return oacR0; - case Transformation::Orientation::R1: - return oacR90; - case Transformation::Orientation::R2: - return oacR180; - case Transformation::Orientation::R3: - return oacR270; - case Transformation::Orientation::MX: - return oacMX; - case Transformation::Orientation::XR: - return oacMXR90; - case Transformation::Orientation::MY: - return oacMY; - case Transformation::Orientation::YR: - return oacMYR90; - default: - throw Error("Unrecognized orientation"); + /** + giving a oaBlock + print the connectivity, mainly used for debug purpose ... + @todo remove when not needed anymore + */ + static void printOABlockTerms(oaBlock* block) { + assert(block); + oaNativeNS ns; + oaDesign* design = block->getDesign(); + cerr << " o Printing " << getOADesignName(design) << " terms" << endl; + oaIter termIter(block->getTerms()); + while (oaTerm* term = termIter.getNext()) { + oaString termName; + term->getName(ns, termName); + cerr << " - " << termName << endl; + } + cerr << endl; } - } - /** - Convertion helper ... - */ - inline void getOATransformFromTransformation(oaTransform& transform, const Transformation& transformation) { - transform.set(transformation.getTx(), - transformation.getTy(), - getOAOrientFromOrientation(transformation.getOrientation())); - } + /** + Convert material from Hurricane to OA ... + @todo verify + */ + static oaMaterial getOAMaterialFromMaterial(const BasicLayer::Material& material) { + switch ( material.getCode() ) { + case BasicLayer::Material::nWell: return oacNWellMaterial; + case BasicLayer::Material::pWell: return oacPWellMaterial; + case BasicLayer::Material::nImplant: return oacNImplantMaterial; + case BasicLayer::Material::pImplant: return oacPImplantMaterial; + case BasicLayer::Material::active: return oacOtherMaterial;//is it OK? + case BasicLayer::Material::poly: return oacPolyMaterial; + case BasicLayer::Material::cut: return oacCutMaterial; + case BasicLayer::Material::metal: return oacMetalMaterial; + case BasicLayer::Material::blockage: + //there is no blockage type but a specific oaLayerBlockage class + return oacOtherMaterial; + case BasicLayer::Material::other: return oacOtherMaterial; + default: + throw Error("Unrecognized material"); + } + } - /** - Convertion helper ... - */ - inline void getOABoxForBox(oaBox& box, const Box& hbox) { - cerr << "getOABoxForBox" << endl; - box.set(hbox.getXMin(), hbox.getYMin(), hbox.getXMax(), hbox.getYMax()); - } + /** + @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; + } + } - /** - Create InstTerm representing connection of nets between instance - always return a non NULL value - */ - inline oaInstTerm* getInstTerm(oaInst* inst, Plug* plug,oaNet* net) { - assert(inst); - assert(plug); - oaNativeNS ns; - oaScalarName scPlugName(ns, getString(plug->getMasterNet()->getName()).c_str()); - oaName instTermName(scPlugName); - oaInstTerm* instTerm = oaInstTerm::find(inst, instTermName); - if (instTerm) { + /** + Convertion helper for Net convertion ... + @todo verify + */ + static oaTermType getOATermTypeFromNetDirection(const Net::Direction& direction) { + switch (direction) { + case Net::Direction::IN: + return oacInputTermType; + case Net::Direction::OUT: + return oacOutputTermType; + case Net::Direction::INOUT: + return oacInputOutputTermType; + case Net::Direction::TRISTATE: + return oacTristateTermType; + case Net::Direction::UNDEFINED: + return oacUnusedTermType;// is it OK ? + default: + throw Error("Unrecognized direction"); + } + } + + /** + Convertion helper for Net convertion ... + @todo verify + */ + static oaSigType getOASigTypeFromNetType(const Net::Type& type) { + switch (type.getCode()) { + case Net::Type::LOGICAL: + return oacSignalSigType; + case Net::Type::CLOCK: + return oacClockSigType; + case Net::Type::POWER: + return oacPowerSigType; + case Net::Type::GROUND: + return oacGroundSigType; + case Net::Type::UNDEFINED: + return oacAnalogSigType;// is it OK ? + default: + throw Error("Unrecognized net type"); + } + } + + /** + Convertion helper ... + */ + static oaOrient getOAOrientFromOrientation(const Transformation::Orientation& orientation) { + switch (orientation) { + case Transformation::Orientation::ID: + return oacR0; + case Transformation::Orientation::R1: + return oacR90; + case Transformation::Orientation::R2: + return oacR180; + case Transformation::Orientation::R3: + return oacR270; + case Transformation::Orientation::MX: + return oacMX; + case Transformation::Orientation::XR: + return oacMXR90; + case Transformation::Orientation::MY: + return oacMY; + case Transformation::Orientation::YR: + return oacMYR90; + default: + throw Error("Unrecognized orientation"); + } + } + + /** + Convertion helper ... + */ + static oaTransform getOATransformFromTransformation(const Transformation& transformation) { + oaTransform transform; + transform.set(transformation.getTx(), + transformation.getTy(), + getOAOrientFromOrientation(transformation.getOrientation())); + return transform; + } + + /** + Convertion helper ... + */ + static oaBox getOABoxFromBox(const Box& b) { + oaBox box; + box.set(b.getXMin(), b.getYMin(), b.getXMax(), b.getYMax()); + return box; + } + + /** + Create InstTerm representing connection of nets between instance + always return a non NULL value + */ + static oaInstTerm* getOAInstTermFromOAInst(oaInst* inst, Plug* plug,oaNet* net) { + assert(inst); + assert(plug); + oaNativeNS ns; + oaScalarName scPlugName(ns, getString(plug->getMasterNet()->getName()).c_str()); + oaName instTermName(scPlugName); + oaInstTerm* instTerm = oaInstTerm::find(inst, instTermName); + if (instTerm) { + return instTerm; + } + oaDesign* design = inst->getMaster(); + assert(design); + oaBlock* masterBlock = design->getTopBlock(); + oaTerm* term = oaTerm::find(masterBlock, instTermName); + assert(term); + cerr << "looking for " << plug->getName() << endl; + printOABlockTerms(masterBlock); + cerr << "oaInstTerm::create" << endl; + instTerm = oaInstTerm::create(net, inst, term); + assert(instTerm); return instTerm; } - oaDesign* design = inst->getMaster(); - assert(design); - oaBlock* masterBlock = design->getTopBlock(); - oaTerm* term = oaTerm::find(masterBlock, instTermName); - assert(term); - cerr << "looking for " << plug->getName() << endl; - printBlockTerms(masterBlock); - cerr << "oaInstTerm::create" << endl; - instTerm = oaInstTerm::create(net, inst, term); - assert(instTerm); - return instTerm; - } - /** - save design stored in a map - */ - inline void saveDesignsInMap(map cell2OAdesign){ - for (map::iterator it = cell2OAdesign.begin(); - it != cell2OAdesign.end(); - ++it) { - cerr << it->first << endl; - oaDesign* design = it->second; - design->save(); - design->close(); + /** + save and close design(s) stored in a map + */ + static void saveOADesignsInMap(map cell2OAdesign){ + for (map::iterator it = cell2OAdesign.begin(); + it != cell2OAdesign.end(); + ++it) { + cerr << it->first << endl; + oaDesign* design = it->second; + design->save(); + design->close(); + } } - } - /** - print the oaLayera in a oaTech ... - */ - inline void printOALayers(oaTech* theOATech){ - assert(theOATech); - oaIter lIter(theOATech->getLayers()); - while(oaLayer* l = lIter.getNext()){ - oaString layerName; - l->getName(layerName); - cerr << " o created oaLayer " << layerName << endl; + /** + print the oaLayera in a oaTech ... + */ + static void printOALayers(oaTech* theOATech){ + assert(theOATech); + oaIter lIter(theOATech->getLayers()); + while(oaLayer* l = lIter.getNext()){ + oaString layerName; + l->getName(layerName); + cerr << " o created oaLayer " << layerName << endl; + } } - } - /** - handling realpath - */ - inline 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(); - } + /** + 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(); + } - /** - generate info from library name - */ - inline pair libInfos(const string& path, - const string& libName){ - oaNativeNS ns; - const char* strNameLib = libName.c_str(); - oaScalarName scNameLib(ns, strNameLib); - string strPathLib = path + '/' + strNameLib; - return make_pair(scNameLib,strPathLib); - } + /** + generate info from library name + */ + static pair libInfos(const string& path, + const string& libName){ + oaNativeNS ns; + const char* strNameLib = libName.c_str(); + oaScalarName scNameLib(ns, strNameLib); + string strPathLib = path + '/' + strNameLib; + return make_pair(scNameLib,strPathLib); + } - /** - 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 - */ - std::vector 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 dirs; - while(firstDelim < len){ - while(secondDelim < len && pstr[secondDelim]!=delim) + /** + 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 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 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++; - string dir = pstr.substr(0,secondDelim); - if(dir.empty()) - break; - dirs.push_back(bfs::path(dir)); - firstDelim = secondDelim; - secondDelim++; + } + return dirs; } - 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. - */ - inline void create_all_dirs(const bfs::path& p){ - if(p.empty() || bfs::exists(p)) - return; - std::vector test; - test = split_in_dirs(p); - std::vector::iterator it = test.begin(); - for(;it != test.end();it++){ - if(it->empty() || bfs::exists(*it)) - continue; - bfs::create_directory(*it); + /** + 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 test; + test = split_in_dirs(p); + std::vector::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 - */ - inline oaLib* openOALib(const pair& infos){ - oaLib *lib = NULL; - try{ - lib = oaLib::find(infos.first); - const char* pathLib = infos.second.c_str(); - if (!lib) { - if (oaLib::exists(pathLib)){ - lib = oaLib::open(infos.first, pathLib); - } - if(!lib){ - if(bfs::path::default_name_check_writable()) - bfs::path::default_name_check(bfs::portable_posix_name); - bfs::path bfs_pathLib = pathLib; - create_all_dirs(bfs_pathLib); - cerr << "creating lib : " << pathLib << endl; - lib = oaLib::create(infos.first, pathLib); + + /** + open oaLib with the info gathered by libPath function + */ + static oaLib* openOALib(const pair& infos){ + oaLib *lib = NULL; + try{ + lib = oaLib::find(infos.first); + const char* pathLib = infos.second.c_str(); + if (!lib) { + if (oaLib::exists(pathLib)){ + lib = oaLib::open(infos.first, pathLib); + } + if(!lib){ + if(bfs::path::default_name_check_writable()) + bfs::path::default_name_check(bfs::portable_posix_name); + bfs::path bfs_pathLib = pathLib; + create_all_dirs(bfs_pathLib); + cerr << "creating lib : " << pathLib << endl; + lib = oaLib::create(infos.first, pathLib); + } } + assert(lib); + }catch(std::exception& e){ + cerr << e.what() << endl; + exit(-1); } - assert(lib); - }catch(std::exception& e){ - cerr << e.what() << endl; - exit(-1); + return lib; } - return lib; - } - inline void createCDS(const pair& infos,const string& path){ - try{ - cerr << "Overwriting cds.lib file begin " << endl; - string cdsPath = path + "/cds.lib"; - oaString oaCDSPath = oaString(cdsPath.c_str()); - oaLibDefList* ldl = oaLibDefList::find(oaCDSPath); - if(!ldl) - ldl = oaLibDefList::get(oaCDSPath, 'a'); - assert(ldl); - assert(ldl->isValid()); - oaLibDef* toAdd = oaLibDef::find(ldl, infos.first); - if(!toAdd) - toAdd = oaLibDef::create(ldl, infos.first, infos.second.c_str()); - ldl->save(); - ldl->destroy();//claim memory - ldl = NULL; - cdsPath.clear(); - cerr << "Overwrited cds.lib file end" << endl; - }catch(oaException& e){ - cerr << "ERROR cds: " << e.getMsg() << endl; - exit(-2); - } - } - - inline oaCell* OADesignToOACell(oaDesign* design){ - assert(design); - oaScalarName cellName; - design->getCellName(cellName); - oaLib* lib = design->getLib(); - oaBoolean gotAccess = false; - gotAccess = lib->getAccess(oacReadLibAccess); - oaCell* cell = oaCell::find(lib,cellName); - if(gotAccess) - lib->releaseAccess(); - assert(cell); - return cell; - } - - //multiplicator of BBOX coordinates - static int convertFactor = 1; - //for namespaces in Hurricane - static const Name OACellLibrariesName("OACellLibraries"); - static const Name OADesignLibrariesName("OADesignLibraries"); - - inline Library* findLibraryByNameInLibrary(const Library* rootLibrary, const Name& libraryName) { - for_each_library(library, rootLibrary->getLibraries()) { - if (library->getName() == libraryName) { - return library; - } - Library* foundLibrary = findLibraryByNameInLibrary(library, libraryName); - if (foundLibrary) { - return foundLibrary; - } - end_for; - } - return NULL; - } - - inline Library* findLibraryByNameInDB(const DataBase* db, const Name& libraryName) { - Library* rootLibrary = db->getRootLibrary(); - if (rootLibrary->getName() == libraryName) { - return rootLibrary; - } - return findLibraryByNameInLibrary(rootLibrary, libraryName); - } - - inline void getAllCells(Library* rootLibrary, set& cellSet) { - for_each_cell(cell, rootLibrary->getCells()) { - cellSet.insert(cell); - end_for; - } - for_each_library(library, rootLibrary->getLibraries()) { - getAllCells(library, cellSet); - end_for; - } - } - - inline Cell* findCellInLibraries(const Library* rootLibrary, const Name& cellName) { - for_each_cell(cell, rootLibrary->getCells()) { - if (cell->getName() == cellName) { - return cell; - } - end_for; - } - for_each_library(library, rootLibrary->getLibraries()) { - Cell* cell = findCellInLibraries(library, cellName); - if (cell) { - return cell; - } - end_for; - } - return NULL; - } - - inline Library* getRootLibrary() { - DataBase* db = DataBase::getDB(); - if (!db) { - return NULL; - } - return db->getRootLibrary(); - } - - /** - function helper - */ - inline Library* getOACellLibraries() { - Library* rootLibrary = getRootLibrary(); - if (!rootLibrary) { - return NULL; - } - for_each_library(library, rootLibrary->getLibraries()) { - if (library->getName() == OACellLibrariesName) { - return library; - } - end_for; - } - return NULL; - } - - /** - helper function - */ - inline Library* getOADesignLibraries() { - Library* rootLibrary = getRootLibrary(); - if (!rootLibrary) { - return NULL; - } - for_each_library(library, rootLibrary->getLibraries()) { - if (library->getName() == OADesignLibrariesName) { - return library; - } - end_for; - } - return NULL; - } - - /** - utility to open a design by name - */ - inline oaView* pickView(oaCell* oa_Cell) { - //oacMaskLayout Type is first - oaView* toReturnView = NULL; - - oaCollection cellViews = oa_Cell->getCellViews(); - oaIter cellViewIter(cellViews); - - while (oaCellView* cellView = cellViewIter.getNext()) { - oaView* view = cellView->getView(); - oaViewType* viewType = view->getViewType(); - oaScalarName viewName; - view->getName(viewName); - if (viewType == oaViewType::get(oacMaskLayout)) { - return view; - } - if (viewType == oaViewType::get(oacSchematic) || - viewType == oaViewType::get(oacNetlist) || - viewType == oaViewType::get(oacSchematicSymbol)) { - toReturnView = view; + /** + create cds.lib file in the path containong OA libs so Cadence (c) software could + open them + */ + static void createCDS(const pair& infos,const string& path){ + try{ + cerr << "Overwriting cds.lib file begin " << endl; + string cdsPath = path + "/cds.lib"; + oaString oaCDSPath = oaString(cdsPath.c_str()); + oaLibDefList* ldl = oaLibDefList::find(oaCDSPath); + if(!ldl) + ldl = oaLibDefList::get(oaCDSPath, 'a'); + assert(ldl); + assert(ldl->isValid()); + oaLibDef* toAdd = oaLibDef::find(ldl, infos.first); + if(!toAdd) + toAdd = oaLibDef::create(ldl, infos.first, infos.second.c_str()); + ldl->save(); + ldl->destroy();//claim memory + ldl = NULL; + cdsPath.clear(); + cerr << "Overwrited cds.lib file end" << endl; + }catch(oaException& e){ + cerr << "ERROR cds: " << e.getMsg() << endl; + exit(-2); } } - return toReturnView; - } - /** - utility to open a design by name - */ - inline oaDesign* openDesign(const oaNameSpace& oaNS, oaCell* oa_Cell) { - oaView* view = pickView(oa_Cell); - if (view != NULL) { - oaScalarName libName; - oaLib* cellLib = oa_Cell->getLib(); - cellLib->getName(libName); + /** + given a oaDesign get the oaCell corresponding + */ + static oaCell* getOACellFromOADesign(oaDesign* design){ + assert(design); oaScalarName cellName; - oa_Cell->getName(cellName); - oaViewType* viewType = view->getViewType(); - oaScalarName viewName; - view->getName(viewName); - return oaDesign::open(libName, cellName, viewName, viewType, 'r'); + design->getCellName(cellName); + oaLib* lib = design->getLib(); + oaBoolean gotAccess = false; + gotAccess = lib->getAccess(oacReadLibAccess); + oaCell* cell = oaCell::find(lib,cellName); + if(gotAccess) + lib->releaseAccess(); + assert(cell); + return cell; } - return NULL; - } - void loadOACellInCell(oaCell* oa_Cell, Cell* cell) { - oaNativeNS oaNS; - oaDesign* cellDesign = openDesign(oaNS, oa_Cell); - - if (cellDesign != NULL) { - oaModule* module = cellDesign->getTopModule(); - oaCollection oaModInsts = module->getInsts(); - oaIter modInstIter(oaModInsts); - while (oaModInst* modInst = modInstIter.getNext()) { - oaString oaModInstStr; - modInst->getName(oaNS, oaModInstStr); - //cerr << "inst : " << oaModInstStr << endl; - oaModule* masterModule = modInst->getMasterModule(); - if (masterModule) { - oaString oaModuleStr; - masterModule->getName(oaNS, oaModuleStr); - //cerr << "master : " << oaModuleStr << endl; - //find hurricane Cell - Cell* masterCell = findCellInLibraries(getRootLibrary(), Name(oaModuleStr)); - if (!masterCell) { - cout << "\n***Quitting. Cannot get MasterCell :" ; - cout << oaModuleStr << endl; - exit(8); - } - Instance* instance = Instance::create(cell, Name(oaModInstStr) ,masterCell); - //cerr << instance << endl; - } else { - cerr << "master : NULL" << endl; - } - }//end while - - //now treat nets - oaCollection oaModNets = module->getNets(); - oaIter oaModNetIter(oaModNets); - while (oaModNet* oa_ModNet = oaModNetIter.getNext()) { - oaString oaModNetStr; - oa_ModNet->getName(oaNS, oaModNetStr); - //cerr << oaModNetStr << endl; - Net* net = cell->getNet(Name(oaModNetStr)); - if (!net) { - net = Net::create(cell, Name(oaModNetStr)); - } - - oaCollection oaModInstTerms = oa_ModNet->getInstTerms(); - oaIter oaModInstTermIter(oaModInstTerms); - while (oaModInstTerm* oa_ModInstTerm = oaModInstTermIter.getNext()) { - oaModInst* modInst = oa_ModInstTerm->getInst(); - oaString oaModInstStr; - modInst->getName(oaNS, oaModInstStr); - //find hurricane instance - Instance* instance = cell->getInstance(Name(oaModInstStr)); - if (!instance) { - cout << "\n***Quitting. Cannot get Instance :" ; - cout << oaModInstStr << endl; - exit(8); - } - oaModTerm* oa_ModTerm = oa_ModInstTerm->getTerm(); - oaString oaModTermStr; - oa_ModTerm->getName(oaNS, oaModTermStr); - Net* masterNet = instance->getMasterCell()->getNet(Name(oaModTermStr)); - if (!masterNet) { - cout << "\n***Quitting. Cannot get Master Net :" ; - cout << oaModTermStr << endl; - exit(8); - } - Plug* plug = instance->getPlug(masterNet); - plug->setNet(net); - //cerr << plug << endl; - } - //cerr << net << endl; + /** + get the rootLibrary of a Hurricane DB + if any + @return the rootLibrary or NULL + */ + static Library* getRootLibrary() { + DataBase* db = DataBase::getDB(); + if (!db) { + return NULL; } - - - oaScalarName cellName; - oa_Cell->getName(cellName); - oaString cellNameString; - cellName.get(cellNameString); - cell->setName(Name(cellNameString)); - cell->setTerminal(false); - - //physical part - oaBlock* block = cellDesign->getTopBlock(); - if (block) { - oaBox oa_box; - block->getBBox(oa_box); - Point lowerLeft(DbU::db(oa_box.lowerLeft().x()), DbU::db(oa_box.lowerLeft().y())); - Point upperRight(DbU::db(oa_box.upperRight().x()), DbU::db(oa_box.upperRight().y())); - cell->setAbutmentBox(Box(lowerLeft, upperRight)); - - oaCollection oaInsts = block->getInsts(); - oaIter oaInstIter(oaInsts); - while (oaInst* oa_Inst = oaInstIter.getNext()) { - oaString oaInstStr; - oa_Inst->getName(oaNS, oaInstStr); - Instance* instance = cell->getInstance(Name(oaInstStr)); - if (instance) { - //cerr << "found " << instance << endl; - oaPlacementStatus placementStatus= oa_Inst->getPlacementStatus(); - switch (placementStatus) { - case oacNonePlacementStatus : - cerr << " none" << endl; - break; - case oacUnplacedPlacementStatus : - cerr << " unplaced" << endl; - break; - case oacPlacedPlacementStatus : - cerr << " placed" << endl; - break; - case oacFixedPlacementStatus : - cerr << " fixed" << endl; - break; - default : - cerr << "other" << endl; - } - oaPoint instOrigin; - oa_Inst->getOrigin(instOrigin); - cerr << instOrigin.x() << " " << instOrigin.y() << endl; - } else { - cerr << "cannot find " << oaInstStr << endl; - } - } - oaSitePattern sitePattern; - block->getSitePattern(sitePattern); - - for (int i = 0; i < sitePattern.getNumElements(); i++) { - const oaSiteRef& siteRef = sitePattern.get(i); - cerr << "site : " << siteRef.siteName() << endl; - } - - oaCollection oaRows = block->getRows(); - oaIter oaRowIter(oaRows); - while (oaRow* oa_Row = oaRowIter.getNext()) { - cerr << "row" << endl; - oaString siteName; - oa_Row->getSiteDefName(siteName); - cerr << siteName << endl; - } - - oaCollection oaAreaBoundaries = block->getBoundaries(); - oaIter oaBoundaryIter(oaAreaBoundaries); - while (oaBoundary* oa_Boundary = oaBoundaryIter.getNext()) { - cerr << "boundary" << endl; - } - } else { - cerr << "no block view " << endl; - } - }//end if (cellDesign != NULL) - } - - inline oaRect* MakeRect(oaBlock *block, - oaTransform &xform, - oaInt4 xformXoffset, - oaLayer* layerPin){ - xform.xOffset() += xformXoffset; - const oaUInt4 lengthPin(3); - const oaUInt4 widthPin(2); - const oaBox boxPin(0, -static_cast(widthPin/2), - lengthPin, static_cast(widthPin/2)); - return oaRect::create(block, - layerPin->getNumber(), - oacDrawingPurposeType, - oaBox(boxPin, xform)); - } - - inline void MakeStub(oaBlock *block, - oaPointArray &pa, - oaInt4 endPointXoffset, - oaLayer* layerPin){ - pa[1].x() += endPointXoffset; - oaLine::create(block, layerPin->getNumber(), oacDrawingPurposeType, pa); - } - - oaString MakeLabel(oaBlock* block, - oaTransform& xform, - const char* label, - oaLayer* layerText){ - oaString str; - const oaUInt4 widthPin(2); - xform.yOffset() += 1 + widthPin/2; - oaText* text = oaText::create(block, - layerText->getNumber(), - oacDrawingPurposeType, - label, - xform.offset(), - oacLowerLeftTextAlign, - oacR0, - oacFixedFont, - 3); - text->getText(str); - return str; - } - - /** - Make a rectangular Pin shape for a Term on a block's symbol. - For the purpose of the schematicSymbol, this pin shape will - be attached to a line "stub extension" sticking out from the - basic symbol shape to represents block's internal Net. - */ - oaPin* MakePinSymbol(oaBlock* block, - oaPoint location, - const char* strNameTerm, - oaInt4 stubLength, - oaOrient rotation, - oaLayer* layerPin, - oaLayer* layerText){ - const oaUInt4 lengthPin(3); - const oaUInt4 widthPin(2); - const oaBox boxPin( 0, -static_cast(widthPin/2), - lengthPin, static_cast(widthPin/2)); - - // boxPin is represented here - // Y-axis - // | - // | lengthPin --> - // |_________ - // | | - // ----|---------|-------- X-axis - // |_________| - // | - // | - // Assume the location argument is the point on the main symbol - // against which the Pin is to be located, centered vertically (Y-axis) - // on that point, left of the point if it is an INPUT pin and right - // of that point if an OUTPUT pin, moved orthogonally away from the - // edge of the gate symbol by a stub of length stubLength representing - // part of the internal net of the gate to which a Term's Pin is attached. - // - // | | - // | OUT | Y__ - // | point o---------|__| - // | | / - // | | / - // | GATE | stubLength - // | | - // A__ | | - // |__|---------o point | - // / | IN | - // / | | - // stubLength | | - - - // Define oaTransform xform to be the location argument (no rotation) - // begin_skel - oaTransform xform( location, rotation ); - // end_skel - - static oaPointArray pa(2); - - // Set both points in pa[] to the value of the location arg. - // (HINT: The allocation size and number of points attributes are DIFFERENT.) - // - // begin_skel - pa.setNumElements(2); - pa[0] = location; - pa[1] = location; - // end_skel - - // Find the term by name (the strNameTerm arg) and set to the term variable - // for reuse later when the Pin is created for that Term. - oaTerm* term = oaTerm::find(block, oaScalarName(oaNativeNS(),strNameTerm)); - - // Create for the Term: - // - // 1. A "stub" Line from the symbol shape to the Pin shape - // (representing a connection to the Block's internal Net) - // - // The pa[] PointArray has already been set up for this Line with the start - // and end Points both set to the proper location on the edge of the symbol - // Shape. Only the second (endPoint) X value must be moved to the LEFT - // or RIGHT (for Input or Output Pins, respectively). Call MakeStub() passing - // in the block to the right edge of the Pin. - // - // 2. A rectangular Shape to represent the Pin itself - // - // Use the MakeRect() utility function to create the Shape of the Pin - // passing to it the template boxPin from the globals singleton, and the - // Transform declared and initialized above. That Transform will move the - // base boxPin from its 0,0 location to the location point on the edge of the - // symbol shape. Also pass in an X offset from that location that moves - // the pinBox to the left or right, depending on whether it's an Input or - // Output Pin. - // - // 3. The Pin itself using the rectangle just created with the same name - // as the Term (arg passed in). Set the access direction for the Pin to - // enable connections from all directions except that on the "stub side". - // The rectangle must be explicitly added to the Pin. - // - // 4. A Text label for the Pin whose text value is the name of the Term. - // Use the MakeLabel() utility function passing in the strNameTerm and - // Transform (which now represents the left edge of the Pin shape properly located. - oaPin* pin = NULL; - switch (term->getTermType()) { - - // If the Pin is an Output type, assume it is on the RIGHT side. - // - // 1. Call MakeStub() with endPointXoffset to the RIGHT by the stubLength. - // 2. Call MakeRect() with an X offset that moves RIGHT by stubLength. - // 3. Construct the oaPin allowing access from top, bottom and right. - // 4. Call MakeLabel(). - // - case oacOutputTermType: - case oacInputOutputTermType: - MakeStub(block, pa, stubLength,layerPin); - pin = oaPin::create(term, oacTop|oacBottom|oacRight); - MakeRect(block, xform, stubLength,layerPin)->addToPin(pin); - MakeLabel(block, xform, strNameTerm,layerText); - break; - - // If the Pin is an Input type, assume it is on the LEFT side. - // - // 1. Call MakeStub() with endPointXoffset to the LEFT by the stubLength. - // 2. Call MakeRect() with an X offset that moves LEFT by - // (stubLength + lengthPin) if the rotation is oacR0. - // 3. Construct the oaPin allowing access from top, bottom, and left. - // 4. Call MakeLabel(). - case oacInputTermType: - default: - MakeStub(block, pa, -stubLength,layerPin); - pin = oaPin::create(term, oacTop|oacBottom|oacLeft); - MakeRect(block,xform, - -stubLength - (rotation == oacR0 - ? lengthPin : 0 ), - layerPin)->addToPin(pin); - MakeLabel(block, xform, strNameTerm,layerText); - break; + return db->getRootLibrary(); } - return pin; - }//MakePinSymbol + /** + get in Hurricane the libraries with OA Design "namespace" : libs from given dev kits + */ + static Library* getOACellLibraries() { + Library* rootLibrary = getRootLibrary(); + if (!rootLibrary) { + return NULL; + } + for_each_library(library, rootLibrary->getLibraries()) { + if (library->getName() == OACellLibrariesName) { + return library; + } + end_for; + } + return NULL; + } -}//end anonymous namespace + /** + get in Hurricane the libraries with OA Design "namespace" : analog designer libs + */ + static Library* getOADesignLibraries() { + Library* rootLibrary = getRootLibrary(); + if (!rootLibrary) { + return NULL; + } + for_each_library(library, rootLibrary->getLibraries()) { + if (library->getName() == OADesignLibrariesName) { + return library; + } + end_for; + } + return NULL; + } + + /** + just pick a view to open : + first try layout then schematic netlist and symbolic + */ + static oaView* pickView(oaCell* oa_Cell) { + //oacMaskLayout Type is first + oaView* toReturnView = NULL; + + oaCollection cellViews = oa_Cell->getCellViews(); + oaIter cellViewIter(cellViews); + + while (oaCellView* cellView = cellViewIter.getNext()) { + oaView* view = cellView->getView(); + oaViewType* viewType = view->getViewType(); + oaScalarName viewName; + view->getName(viewName); + if (viewType == oaViewType::get(oacMaskLayout)) { + return view; + } + if (viewType == oaViewType::get(oacSchematic) || + viewType == oaViewType::get(oacNetlist) || + viewType == oaViewType::get(oacSchematicSymbol)) { + toReturnView = view; + } + } + return toReturnView; + } + + /** + utility to open a design from a oaCell (i.e from a kit) + */ + static oaDesign* openOADesign(oaCell* oa_Cell) { + oaNativeNS oaNS; + oaView* view = pickView(oa_Cell); + if (view != NULL) { + oaScalarName libName; + oaLib* cellLib = oa_Cell->getLib(); + cellLib->getName(libName); + oaScalarName cellName; + oa_Cell->getName(cellName); + oaViewType* viewType = view->getViewType(); + oaScalarName viewName; + view->getName(viewName); + return oaDesign::open(libName, cellName, viewName, viewType, 'r'); + } + return NULL; + } + };//struct oaCommon +}//end CRL_OA namespace #endif//HAVE_OPENACCESS diff --git a/crlcore/src/ccore/openaccess/OpenAccessDriver.cpp b/crlcore/src/ccore/openaccess/OpenAccessDriver.cpp index 161486cb..ab79456b 100644 --- a/crlcore/src/ccore/openaccess/OpenAccessDriver.cpp +++ b/crlcore/src/ccore/openaccess/OpenAccessDriver.cpp @@ -1,5 +1,5 @@ // -*-compile-command:"cd ../../../../.. && make"-*- -// Time-stamp: "2010-08-04 16:57:08" - OpenAccessDriver.cpp +// Time-stamp: "2010-08-06 01:22:51" - OpenAccessDriver.cpp // x-----------------------------------------------------------------x // | This file is part of the hurricaneAMS Software. | // | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved | @@ -32,7 +32,7 @@ using namespace Hurricane; #include "OpenAccessCommon.h" namespace { - + using namespace CRL_OA; #ifdef HAVE_OPENACCESS /** @@ -89,7 +89,7 @@ namespace { if (!_technology) { throw Error("no technology"); } - realPath(_path); + oaFuncs::realPath(_path); cerr << "realpath: " << _path << endl; } @@ -97,13 +97,13 @@ namespace { cerr << "SAVING ALL" << endl; _oaTech->save(); _oaTech->close(); - saveDesignsInMap(_cell2OADesign4Netlist); + oaFuncs::saveOADesignsInMap(_cell2OADesign4Netlist); _cell2OADesign4Netlist.clear(); - saveDesignsInMap(_cell2OADesign4Schematic); + oaFuncs::saveOADesignsInMap(_cell2OADesign4Schematic); _cell2OADesign4Schematic.clear(); - saveDesignsInMap(_cell2OADesign4Symbolic); + oaFuncs::saveOADesignsInMap(_cell2OADesign4Symbolic); _cell2OADesign4Symbolic.clear(); - saveDesignsInMap(_cell2OADesign4Layout); + oaFuncs::saveOADesignsInMap(_cell2OADesign4Layout); _cell2OADesign4Layout.clear(); for (Library2OALibMap::iterator it = _library2OALib.begin(); it != _library2OALib.end(); @@ -128,9 +128,9 @@ namespace { // 1) create or open library cerr << "lib path : " << _path << endl; - pair infos=libInfos(_path, - getString(library->getName())); - oaLib *lib = openOALib(infos); + pair infos = oaFuncs::libInfos(_path, + getString(library->getName())); + oaLib *lib = oaFuncs::openOALib(infos); _library2OALib[library] = lib; #if 0 @@ -147,7 +147,7 @@ namespace { } #endif // 4) create, update library list file - createCDS(infos,_path); + oaFuncs::createCDS(infos,_path); infos.second.clear(); return lib; @@ -203,7 +203,7 @@ namespace { } BasicLayer* bLayer = dynamic_cast(layer); aOALayer = oaPhysicalLayer::create(theOATech, layerName, generateLayerID(bLayer), - bLayer ? getOAMaterial(bLayer->getMaterial()) + bLayer ? oaFuncs::getOAMaterialFromMaterial(bLayer->getMaterial()) : oaMaterial(oacOtherMaterial)); assert(aOALayer); @@ -345,7 +345,7 @@ namespace { cerr << "STD:" << e.what() << endl; exit(-1); } - printOALayers(theOATech); + oaFuncs::printOALayers(theOATech); return theOATech; } @@ -379,8 +379,7 @@ namespace { oaScalarInst* blockInst = oaScalarInst::find(topBlock, scInstName); if(!blockInst){ - oaTransform transform; - getOATransformFromTransformation(transform, instance->getTransformation()); + oaTransform transform = oaFuncs::getOATransformFromTransformation(instance->getTransformation()); blockInst = oaScalarInst::create(topBlock, masterDesign, scInstName, transform); } _instance2OAInst[instance] = blockInst; @@ -399,7 +398,7 @@ namespace { Instance2OAInstsMap::iterator it = _instance2OAInst.find(instance); assert(it != _instance2OAInst.end()); oaInst* blockInst = it->second; - oaInstTerm* instTerm = getInstTerm(blockInst, plug,net); + oaInstTerm* instTerm = oaFuncs::getOAInstTermFromOAInst(blockInst, plug,net); assert(instTerm); return instTerm; } @@ -423,8 +422,7 @@ namespace { cerr << "getOARectFromComponent" << endl; assert(component); assert(topBlock); - oaBox box; - getOABoxForBox(box, component->getBoundingBox()); + oaBox box = oaFuncs::getOABoxFromBox(component->getBoundingBox()); Layer* layer = (Layer*) component->getLayer(); assert(layer); oaPhysicalLayer* physLayer = getOALayerFromLayer(layer,_oaTech); @@ -451,15 +449,15 @@ namespace { if(blockNet) return blockNet; assert(!blockNet); - blockNet = oaScalarNet::create(topBlock, scNetName, getOASigType(net->getType())); + blockNet = oaScalarNet::create(topBlock, scNetName, oaFuncs::getOASigTypeFromNetType(net->getType())); assert(blockNet); - oaScalarTerm::create(blockNet, scNetName, getOATermType(net->getDirection())); + oaScalarTerm::create(blockNet, scNetName, oaFuncs::getOATermTypeFromNetDirection(net->getDirection())); if (net->isExternal()) { oaPin* pin = getOAPinFromNet(net,blockNet); Components externalComponents = NetExternalComponents::get(net); for_each_component(component, externalComponents) { oaRect* rect = getOARectFromComponent(component,topBlock); -// rect->addToPin(pin); + rect->addToPin(pin); end_for; } } @@ -651,6 +649,9 @@ namespace { getOARectFromSlice(slice,topBlock); end_for; } + //get and update boundingBox + oaBox boundingBox; + topBlock->getBBox(boundingBox); return designCellView; } @@ -670,25 +671,25 @@ namespace { oaDesign* netlistView = createOAasNetlist(cell); assert(netlistView); - oaCell* c1 = OADesignToOACell(netlistView); + oaCell* c1 = oaFuncs::getOACellFromOADesign(netlistView); assert(c1); oaDesign* symbolicView = addSymbol(cell,netlistView); assert(symbolicView); - oaCell* c2 = OADesignToOACell(symbolicView); + oaCell* c2 = oaFuncs::getOACellFromOADesign(symbolicView); assert(c2); oaDesign* schematicView = addSchematic(cell,symbolicView); assert(schematicView); - oaCell* c3 = OADesignToOACell(schematicView); + oaCell* c3 = oaFuncs::getOACellFromOADesign(schematicView); assert(c3); oaDesign* layoutView = addLayout(cell,schematicView); assert(layoutView); - oaCell* c4 = OADesignToOACell(layoutView); + oaCell* c4 = oaFuncs::getOACellFromOADesign(layoutView); assert(c4); //3) we check it's the same oaCell for all designs @@ -698,14 +699,14 @@ namespace { } oaCell* getOACellForCell(const Cell* cell) { - return OADesignToOACell( getOADesignForCell(cell) ); + return oaFuncs::getOACellFromOADesign( getOADesignForCell(cell) ); } };//OADriver class #endif -}//namespace +}//namespace CRL_OA namespace CRL { - oaCell* OpenAccess::oaDriver(const string& path, Cell* cell) { + void OpenAccess::oaDriver(const string& path, Cell* cell) { oaCell* convertedCell = NULL; #ifdef HAVE_OPENACCESS //for the moment a driver for hurricaneAMS @@ -715,7 +716,7 @@ namespace CRL { oaDesignInit(oacAPIMajorRevNumber, oacAPIMinorRevNumber, oacDataModelRevNumber); - + OADriver oaDriver(path); convertedCell = oaDriver.getOACellForCell(cell); }catch (oaException &e) { @@ -728,6 +729,6 @@ namespace CRL { #else cerr << "\nDummy OpenAccess driver call for " << path << endl; #endif - return convertedCell; + return; } } diff --git a/crlcore/src/ccore/openaccess/OpenAccessParser.cpp b/crlcore/src/ccore/openaccess/OpenAccessParser.cpp index a8ba03a3..38899e69 100644 --- a/crlcore/src/ccore/openaccess/OpenAccessParser.cpp +++ b/crlcore/src/ccore/openaccess/OpenAccessParser.cpp @@ -1,5 +1,5 @@ // -*-compile-command:"cd ../../../../.. && make"-*- -// Time-stamp: "2010-08-04 15:45:06" - OpenAccessParser.cpp +// Time-stamp: "2010-08-06 01:40:58" - OpenAccessParser.cpp // x-----------------------------------------------------------------x // | This file is part of the hurricaneAMS Software. | // | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved | @@ -28,7 +28,7 @@ using namespace Hurricane; #include "OpenAccessCommon.h" namespace { - + using namespace CRL_OA; #ifdef HAVE_OPENACCESS class OAParser{ private: @@ -77,7 +77,7 @@ namespace { return NULL; } Name cellName(cellNameStr); - Cell* cell = findCellInLibraries(getOADesignLibraries(), cellName); + Cell* cell = oaFuncs::findCellInLibraries(oaFuncs::getOADesignLibraries(), cellName); if (!cell) { return NULL; } @@ -96,22 +96,27 @@ namespace { return cell; } - void loadOALib(const string& libNameStr, const string& libPathStr, bool asDesignLibrary) { + /** + heart of the parser algorithm + */ + oaLib* loadOALib(const string& libNameStr, const string& libPathStr, bool asDesignLibrary) { + oaNativeNS oaNS; + oaString libNameOAStr(libNameStr.c_str()); + oaScalarName libOAName(oaNS, libNameOAStr); Name libName(libNameStr); Name2LibMap::const_iterator nit = _name2LibMap.find(libName); if (nit != _name2LibMap.end()) { Library* library = nit->second; //verify that it's the same library : name and path cerr << "already loaded" << endl; - return; + return oaLib::find(libOAName); } - oaNativeNS oaNS; - oaString libNameOAStr(libNameStr.c_str()); - oaScalarName libOAName(oaNS, libNameOAStr); + + oaLib* oaLibrary = NULL; try { - oaLib* oaLibrary = oaLib::open(libOAName, libPathStr.c_str()); + oaLibrary = oaLib::open(libOAName, libPathStr.c_str()); if (oaLibrary->isReadable()) { if (!oaLibrary->getAccess(oacReadLibAccess)) { cout << "\n***Quitting. Cannot get LibAccess\n" ; @@ -127,16 +132,16 @@ namespace { cerr << "No DataBase" << endl; exit(8); } - if (findLibraryByNameInDB(db, libraryName)) { + if (oaFuncs::findLibraryByNameInDB(db, libraryName)) { cerr << "ERROR" << endl; exit(8); } Library* library; if (asDesignLibrary) { - library = Library::create(getOADesignLibraries(), Name(libNameStr)); + library = Library::create(oaFuncs::getOADesignLibraries(), Name(libNameStr)); } else { - library = Library::create(getOACellLibraries(), Name(libNameStr)); + library = Library::create(oaFuncs::getOACellLibraries(), Name(libNameStr)); } cerr << library << endl; @@ -151,7 +156,7 @@ namespace { cerr << cellNameString << endl; - oaDesign* cellDesign = openDesign(oaNS, cell); + oaDesign* cellDesign = oaFuncs::openOADesign(cell); if (cellDesign != NULL) { Cell* hCell = NULL; //logic part @@ -288,9 +293,12 @@ namespace { cout << "ERROR: " << excp.getMsg() << endl; exit(1); } - + return oaLibrary; } + /** + heart of the parser algorithm + */ void oaTechnology2Technology(oaLib* oaLibrary) { try { oaTech* tech = oaTech::open(oaLibrary); @@ -338,29 +346,182 @@ namespace { } void getDesigns(set& designCellSet) { - getAllCells(getOADesignLibraries(), designCellSet); + oaFuncs::getAllCells(oaFuncs::getOADesignLibraries(), designCellSet); } + + /** + heart of the parser algorithm + */ + static void loadOACellInCell(oaCell* oa_Cell, Cell* cell) { + oaNativeNS oaNS; + oaDesign* cellDesign = oaFuncs::openOADesign(oa_Cell); + + if (cellDesign != NULL) { + oaModule* module = cellDesign->getTopModule(); + oaCollection oaModInsts = module->getInsts(); + oaIter modInstIter(oaModInsts); + while (oaModInst* modInst = modInstIter.getNext()) { + oaString oaModInstStr; + modInst->getName(oaNS, oaModInstStr); + //cerr << "inst : " << oaModInstStr << endl; + oaModule* masterModule = modInst->getMasterModule(); + if (masterModule) { + oaString oaModuleStr; + masterModule->getName(oaNS, oaModuleStr); + //cerr << "master : " << oaModuleStr << endl; + //find hurricane Cell + Cell* masterCell = oaFuncs::findCellInLibraries(oaFuncs::getRootLibrary(), Name(oaModuleStr)); + if (!masterCell) { + cout << "\n***Quitting. Cannot get MasterCell :" ; + cout << oaModuleStr << endl; + exit(8); + } + Instance* instance = Instance::create(cell, Name(oaModInstStr) ,masterCell); + //cerr << instance << endl; + } else { + cerr << "master : NULL" << endl; + } + }//end while + + //now treat nets + oaCollection oaModNets = module->getNets(); + oaIter oaModNetIter(oaModNets); + while (oaModNet* oa_ModNet = oaModNetIter.getNext()) { + oaString oaModNetStr; + oa_ModNet->getName(oaNS, oaModNetStr); + //cerr << oaModNetStr << endl; + Net* net = cell->getNet(Name(oaModNetStr)); + if (!net) { + net = Net::create(cell, Name(oaModNetStr)); + } + + oaCollection oaModInstTerms = oa_ModNet->getInstTerms(); + oaIter oaModInstTermIter(oaModInstTerms); + while (oaModInstTerm* oa_ModInstTerm = oaModInstTermIter.getNext()) { + oaModInst* modInst = oa_ModInstTerm->getInst(); + oaString oaModInstStr; + modInst->getName(oaNS, oaModInstStr); + //find hurricane instance + Instance* instance = cell->getInstance(Name(oaModInstStr)); + if (!instance) { + cout << "\n***Quitting. Cannot get Instance :" ; + cout << oaModInstStr << endl; + exit(8); + } + oaModTerm* oa_ModTerm = oa_ModInstTerm->getTerm(); + oaString oaModTermStr; + oa_ModTerm->getName(oaNS, oaModTermStr); + Net* masterNet = instance->getMasterCell()->getNet(Name(oaModTermStr)); + if (!masterNet) { + cout << "\n***Quitting. Cannot get Master Net :" ; + cout << oaModTermStr << endl; + exit(8); + } + Plug* plug = instance->getPlug(masterNet); + plug->setNet(net); + //cerr << plug << endl; + } + //cerr << net << endl; + } + + + oaScalarName cellName; + oa_Cell->getName(cellName); + oaString cellNameString; + cellName.get(cellNameString); + cell->setName(Name(cellNameString)); + cell->setTerminal(false); + + //physical part + oaBlock* block = cellDesign->getTopBlock(); + if (block) { + oaBox oa_box; + block->getBBox(oa_box); + Point lowerLeft(DbU::db(oa_box.lowerLeft().x()), DbU::db(oa_box.lowerLeft().y())); + Point upperRight(DbU::db(oa_box.upperRight().x()), DbU::db(oa_box.upperRight().y())); + cell->setAbutmentBox(Box(lowerLeft, upperRight)); + + oaCollection oaInsts = block->getInsts(); + oaIter oaInstIter(oaInsts); + while (oaInst* oa_Inst = oaInstIter.getNext()) { + oaString oaInstStr; + oa_Inst->getName(oaNS, oaInstStr); + Instance* instance = cell->getInstance(Name(oaInstStr)); + if (instance) { + //cerr << "found " << instance << endl; + oaPlacementStatus placementStatus= oa_Inst->getPlacementStatus(); + switch (placementStatus) { + case oacNonePlacementStatus : + cerr << " none" << endl; + break; + case oacUnplacedPlacementStatus : + cerr << " unplaced" << endl; + break; + case oacPlacedPlacementStatus : + cerr << " placed" << endl; + break; + case oacFixedPlacementStatus : + cerr << " fixed" << endl; + break; + default : + cerr << "other" << endl; + } + oaPoint instOrigin; + oa_Inst->getOrigin(instOrigin); + cerr << instOrigin.x() << " " << instOrigin.y() << endl; + } else { + cerr << "cannot find " << oaInstStr << endl; + } + } + oaSitePattern sitePattern; + block->getSitePattern(sitePattern); + + for (int i = 0; i < sitePattern.getNumElements(); i++) { + const oaSiteRef& siteRef = sitePattern.get(i); + cerr << "site : " << siteRef.siteName() << endl; + } + + oaCollection oaRows = block->getRows(); + oaIter oaRowIter(oaRows); + while (oaRow* oa_Row = oaRowIter.getNext()) { + cerr << "row" << endl; + oaString siteName; + oa_Row->getSiteDefName(siteName); + cerr << siteName << endl; + } + + oaCollection oaAreaBoundaries = block->getBoundaries(); + oaIter oaBoundaryIter(oaAreaBoundaries); + while (oaBoundary* oa_Boundary = oaBoundaryIter.getNext()) { + cerr << "boundary" << endl; + } + } else { + cerr << "no block view " << endl; + } + }//end if (cellDesign != NULL) + }//end loadOACellInCell };//OAParser class #endif }//namespace -using namespace oa; namespace CRL { - Cell* OpenAccess::oaCellParser(oaCell* cell){ + Cell* OpenAccess::oaCellParser(const std::string& libPath, + const std::string& libName, const std::string& cellName) { Cell* convertedCell = NULL; - if(!cell) - return NULL; #ifdef HAVE_OPENACCESS try { oaDesignInit(oacAPIMajorRevNumber, oacAPIMinorRevNumber, oacDataModelRevNumber); - + OAParser oaParser; - oaScalarName scalarCellName; - oaString cellName; - cell->getName(scalarCellName); - convertedCell = oaParser.getCell(static_cast(cellName)); + oaScalarName scalarCellName(oaNativeNS(),cellName.c_str()); + + oaLib* oaLibrary = oaParser.loadOALib(libName, libPath, true); + Cell* hcell = oaParser.getCell(cellName); + oaCell* cell = oaCell::find(oaLibrary,scalarCellName); + oaParser.loadOACellInCell(cell,hcell); + }catch (oaException &e) { cerr << "OA::ERROR => " << e.getMsg() << endl; exit(1); @@ -373,14 +534,5 @@ namespace CRL { #endif return convertedCell; } - - Library* OpenAccess::oaLibParser(oaLib* lib){ -#ifdef HAVE_OPENACCESS - cerr << "\nto implement ... " << endl; -#else - cerr << "\nDummy OpenAccess driver call for " << path << endl; -#endif - return NULL; - } }