diff --git a/vlsisapd/CMakeLists.txt b/vlsisapd/CMakeLists.txt index 22771642..efe0df40 100644 --- a/vlsisapd/CMakeLists.txt +++ b/vlsisapd/CMakeLists.txt @@ -9,4 +9,5 @@ FIND_PACKAGE(LibXml2 REQUIRED) ADD_SUBDIRECTORY(agds) ADD_SUBDIRECTORY(cif) ADD_SUBDIRECTORY(openChams) +ADD_SUBDIRECTORY(dtr) ADD_SUBDIRECTORY(cmake_modules) diff --git a/vlsisapd/cmake_modules/FindIO.cmake b/vlsisapd/cmake_modules/FindIO.cmake index a205c3e0..5f742dac 100644 --- a/vlsisapd/cmake_modules/FindIO.cmake +++ b/vlsisapd/cmake_modules/FindIO.cmake @@ -26,68 +26,44 @@ MACRO(SETUP_SEARCH_DIR project) ENDIF( NOT("$ENV{${project}_TOP}" STREQUAL "") ) ENDMACRO(SETUP_SEARCH_DIR project) +MACRO(SET_FOUND project) + IF(${project}_INCLUDE_DIR AND ${project}_LIBRARY) + SET(${project}_FOUND TRUE) + ELSE(${project}_INCLUDE_DIR AND ${project}_LIBRARY) + SET(${project}_FOUND FALSE) + ENDIF(${project}_INCLUDE_DIR AND ${project}_LIBRARY) +ENDMACRO(SET_FOUND project) + SETUP_SEARCH_DIR(IO) IF(IO_DIR_SEARCH) # AGDS - FIND_PATH(AGDS_INCLUDE_DIR - NAMES io/agds/GdsLibrary.h - PATHS ${IO_DIR_SEARCH} - PATH_SUFFIXES include - ) - FIND_LIBRARY(AGDS_LIBRARY - NAMES agds - PATHS ${IO_DIR_SEARCH} - PATH_SUFFIXES lib - ) - IF(AGDS_INCLUDE_DIR AND AGDS_LIBRARY) - SET(AGDS_FOUND TRUE) - #SET(IO_FOUND TRUE) - # SET(IO_LIBRARIES ${AGDS_LIBRARY}) - ELSE(AGDS_INCLUDE_DIR AND AGDS_LIBRARY) - SET(AGDS_FOUND FALSE) - # SET(IO_LIBRARIES) - ENDIF(AGDS_INCLUDE_DIR AND AGDS_LIBRARY) + FIND_PATH (AGDS_INCLUDE_DIR NAMES io/agds/GdsLibrary.h PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES include) + FIND_LIBRARY(AGDS_LIBRARY NAMES agds PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES lib) + SET_FOUND(AGDS) # CIF - FIND_PATH(CIF_INCLUDE_DIR - NAMES io/cif/CifCircuit.h - PATHS ${IO_DIR_SEARCH} - PATH_SUFFIXES include - ) - FIND_LIBRARY(CIF_LIBRARY - NAMES cif - PATHS ${IO_DIR_SEARCH} - PATH_SUFFIXES lib - ) - IF(CIF_INCLUDE_DIR AND CIF_LIBRARY) - SET(CIF_FOUND TRUE) - ELSE(CIF_INCLUDE_DIR AND CIF_LIBRARY) - SET(CIF_FOUND FALSE) - ENDIF(CIF_INCLUDE_DIR AND CIF_LIBRARY) + FIND_PATH (CIF_INCLUDE_DIR NAMES io/cif/CifCircuit.h PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES include) + FIND_LIBRARY(CIF_LIBRARY NAMES cif PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES lib) + SET_FOUND(CIF) # OPENCHAMS - FIND_PATH(OPENCHAMS_INCLUDE_DIR - NAMES io/openChams/Circuit.h - PATHS ${IO_DIR_SEARCH} - PATH_SUFFIXES include - ) - FIND_LIBRARY(OPENCHAMS_LIBRARY - NAMES openChams - PATHS ${IO_DIR_SEARCH} - PATH_SUFFIXES lib - ) - IF(OPENCHAMS_INCLUDE_DIR AND OPENCHAMS_LIBRARY) - SET(OPENCHAMS_FOUND TRUE) - ELSE(OPENCHAMS_INCLUDE_DIR AND OPENCHAMS_LIBRARY) - SET(OPENCHAMS_FOUND FALSE) - ENDIF(OPENCHAMS_INCLUDE_DIR AND OPENCHAMS_LIBRARY) + FIND_PATH (OPENCHAMS_INCLUDE_DIR NAMES io/openChams/Circuit.h PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES include) + FIND_LIBRARY(OPENCHAMS_LIBRARY NAMES openChams PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES lib) + SET_FOUND(OPENCHAMS) + + # DTR + FIND_PATH (DTR_INCLUDE_DIR NAMES io/dtr/Techno.h PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES include) + FIND_LIBRARY(DTR_LIBRARY NAMES dtr PATHS ${IO_DIR_SEARCH} PATH_SUFFIXES lib) + SET_FOUND(DTR) - IF(AGDS_FOUND AND CIF_FOUND AND OPENCHAMS_FOUND) + IF(AGDS_FOUND AND CIF_FOUND AND OPENCHAMS_FOUND AND DTR_FOUND) SET(IO_FOUND TRUE) - ELSE(AGDS_FOUND AND CIF_FOUND AND OPENCHAMS_FOUND) + ELSE(AGDS_FOUND AND CIF_FOUND AND OPENCHAMS_FOUND AND DTR_FOUND) SET(IO_FOUND FALSE) - ENDIF(AGDS_FOUND AND CIF_FOUND AND OPENCHAMS_FOUND) + ENDIF(AGDS_FOUND AND CIF_FOUND AND OPENCHAMS_FOUND AND DTR_FOUND) +ELSE(IO_DIR_SEARCH) + MESSAGE("-- Cannot find IO_LIBRARIES since IO_DIR_SEARCH is not defined.") ENDIF(IO_DIR_SEARCH) IF (NOT IO_FOUND) diff --git a/vlsisapd/dtr/CMakeLists.txt b/vlsisapd/dtr/CMakeLists.txt new file mode 100644 index 00000000..4b7537b5 --- /dev/null +++ b/vlsisapd/dtr/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY(src) diff --git a/vlsisapd/dtr/src/CMakeLists.txt b/vlsisapd/dtr/src/CMakeLists.txt new file mode 100644 index 00000000..f00a7f55 --- /dev/null +++ b/vlsisapd/dtr/src/CMakeLists.txt @@ -0,0 +1,16 @@ +INCLUDE_DIRECTORIES(${IO_SOURCE_DIR}/dtr/src ${LIBXML2_INCLUDE_DIR}) + +SET ( hpps io/dtr/Techno.h + io/dtr/Rules.h + io/dtr/Name.h + io/dtr/DTRException.h ) + +SET ( cpps Techno.cpp + Name.cpp ) + +ADD_LIBRARY(dtr ${cpps}) + +TARGET_LINK_LIBRARIES(dtr ${LIBXML2_LIBRARIES}) + +INSTALL(TARGETS dtr DESTINATION /lib) +INSTALL(FILES ${hpps} DESTINATION /include/io/dtr) diff --git a/vlsisapd/dtr/src/Name.cpp b/vlsisapd/dtr/src/Name.cpp new file mode 100644 index 00000000..1353865f --- /dev/null +++ b/vlsisapd/dtr/src/Name.cpp @@ -0,0 +1,65 @@ +/* + * Name.cpp + * DTR + * + * Created by damien dupuis on 01/04/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +using namespace std; + +#include "io/dtr/Name.h" + +namespace DTR { +unsigned long Name::_globalId = 0; +map Name::_dict; + +Name::Name(string str) : _str(NULL) { + map::iterator it = _dict.find(str); + if (it != _dict.end()) { + _id = (*it).second; + _str = &((*it).first); + } else { + _id = _globalId++; + it = _dict.insert(_dict.begin(), make_pair(str, _id)); + _str = &((*it).first); + } +} + +Name::Name(const char* c) : _str(NULL) { + string str(c); + map::iterator it = _dict.find(str); + if (it != _dict.end()) { + _id = (*it).second; + _str = &((*it).first); + } else { + _id = _globalId++; + it = _dict.insert(_dict.begin(), make_pair(str, _id)); + _str = &((*it).first); + } +} + +bool Name::operator==(const Name& n) { + return (_id == n._id); +} + +bool Name::operator==(const string& str) { + Name n(str); + return (_id == n._id); +} + +bool Name::operator!=(const Name& n) { + return (_id != n._id); +} + +bool Name::operator!=(const string& str) { + Name n(str); + return (_id != n._id); +} + +bool Name::operator<(const Name n) const { + return (_id < n._id); +} +} // namespace + diff --git a/vlsisapd/dtr/src/Techno.cpp b/vlsisapd/dtr/src/Techno.cpp new file mode 100644 index 00000000..bc4fa6c1 --- /dev/null +++ b/vlsisapd/dtr/src/Techno.cpp @@ -0,0 +1,222 @@ +/* + * Techno.cpp + * DTR + * + * Created by damien dupuis on 01/04/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +#include +#include +#include +#include +using namespace std; + +#include +#include + +#include "io/dtr/Techno.h" +#include "io/dtr/Rules.h" +#include "io/dtr/DTRException.h" + +namespace { + template T getValue(xmlChar* str) { + std::istringstream iss; + iss.str((const char*) str); + T res; + iss >> res; + return res; + } +} + +namespace DTR { +Techno::Techno(Name name, Name unit) : _name(name), _unit(unit) {} + +Rule* Techno::addRule (Name type, double value, Name ref, Name layer1, Name layer2) { + Rule* rule = new Rule(type, value, ref, layer1, layer2); + _rules.push_back(rule); + return rule; +} + +ARule* Techno::addARule (Name type, double value, Name ref, Name layer1, Name layer2) { + ARule* arule = new ARule(type, value, ref, layer1, layer2); + _rules.push_back(arule); + return arule; +} + +double Techno::getValue(Name type, Name layer1, Name layer2) { + bool testL1 = (layer1 == Name("")) ? false : true; + bool testL2 = (layer2 == Name("")) ? false : true; + + for (size_t i = 0 ; i < _rules.size() ; i++) { + Rule* rule = _rules[i]; + if (rule->getType() == type) { + if (testL1) { + if (rule->getLayer1() == layer1) { + if (testL2) { + if (rule->getLayer2() == layer2) { + return rule->getValue(); + } + } else { + return rule->getValue(); + } + } + } else { + return rule->getValue(); + } + } + } + string error ("[ERROR] Could not found rule: "); + error += type.getString(); + error += "."; + error += layer1.getString(); + error += "."; + error += layer2.getString(); + error += "."; + throw DTRException(error); +} + +Techno* Techno::readFromFile(const string filePath) { + LIBXML_TEST_VERSION; + Techno* techno = NULL; + xmlDoc* doc = xmlReadFile(filePath.c_str(), NULL, 0); + if (doc == NULL) { + string error ("[ERROR] Failed to parse: "); + error += filePath; + throw DTRException(error); + //return NULL; + } + xmlNode* rootElement = xmlDocGetRootElement(doc); + if (rootElement->type == XML_ELEMENT_NODE && xmlStrEqual(rootElement->name, (xmlChar*)"technology")) { + xmlChar* technoNameC = xmlGetProp(rootElement, (xmlChar*)"name"); + xmlChar* technoUnitC = xmlGetProp(rootElement, (xmlChar*)"unit"); + + if (technoNameC && technoUnitC) { + Name name ((const char*)technoNameC); + Name unit ((const char*)technoUnitC); + techno = new Techno(name, unit); + } else { + throw DTRException("[ERROR] 'technology' node must have 'name' and 'unit' properties."); + return NULL; + } + + + xmlNode* child = rootElement->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (!xmlStrEqual(node->name, (xmlChar*)"physical_rules")) { + throw DTRException("[ERROR] only 'physical_rules' node is allowed under 'technology' node."); + return NULL; + } + for (xmlNode* subnode = node->children ; subnode ; subnode = subnode->next) { + if (subnode->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(subnode->name, (xmlChar*)"rule")) { + xmlChar* nameC = xmlGetProp(subnode, (xmlChar*)"name" ); + xmlChar* layerC = xmlGetProp(subnode, (xmlChar*)"layer" ); + xmlChar* layer1C = xmlGetProp(subnode, (xmlChar*)"layer1"); + xmlChar* layer2C = xmlGetProp(subnode, (xmlChar*)"layer2"); + xmlChar* valueC = xmlGetProp(subnode, (xmlChar*)"value" ); + xmlChar* refC = xmlGetProp(subnode, (xmlChar*)"ref" ); + xmlChar* typeC = xmlGetProp(subnode, (xmlChar*)"type" ); + + Rule* rule = NULL; + if (nameC && layer1C && layer2C && valueC && refC) { // rule with two layers + Name name ((const char*)nameC); + Name ref ((const char*)refC); + Name layer1 ((const char*)layer1C); + Name layer2 ((const char*)layer2C); + double value = ::getValue(valueC); + rule = techno->addRule(name, value, ref, layer1, layer2); + } else if (nameC && layerC && valueC && refC) {// rule with only one layer + Name name ((const char*)nameC); + Name ref ((const char*)refC); + Name layer ((const char*)layerC); + double value = ::getValue(valueC); + rule = techno->addRule(name, value, ref, layer); + } else if (nameC && valueC && refC) { // rule without layer + Name name ((const char*)nameC); + Name ref ((const char*)refC); + double value = ::getValue(valueC); + rule = techno->addRule(name, value, ref); + } else { // invalid case + throw DTRException("[ERROR] properties of 'rule' node must be ('name', 'value', 'ref') or ('name', 'layer', 'value', 'ref') or ('name', 'layer1', 'layer2', 'value', 'ref')."); + return NULL; + } + if (typeC) { + Name type ((const char*)typeC); + rule->setType(type); + } + } else if (xmlStrEqual(subnode->name, (xmlChar*)"arule")) { + xmlChar* nameC = xmlGetProp(subnode, (xmlChar*)"name" ); + xmlChar* layer1C = xmlGetProp(subnode, (xmlChar*)"layer1"); + xmlChar* layer2C = xmlGetProp(subnode, (xmlChar*)"layer2"); + xmlChar* valueC = xmlGetProp(subnode, (xmlChar*)"value" ); + xmlChar* refC = xmlGetProp(subnode, (xmlChar*)"ref" ); + if (nameC && layer1C && layer2C && valueC && refC) { + Name name ((const char*)nameC); + Name layer1 ((const char*)layer1C); + Name layer2 ((const char*)layer2C); + Name ref ((const char*)refC); + double value = ::getValue(valueC); + techno->addARule(name, value, ref, layer1, layer2); + } else { + throw DTRException("[ERROR] 'arule' node must have 'name', 'layer1', 'layer2', 'value' and 'ref' properties."); + return NULL; + } + } else { + throw DTRException("[ERROR] only 'rule' and 'arule' nodes are allowed under 'physical_rules' node."); + } + } + } + } + } + } + return techno; +} + +bool Techno::writeToFile(string filePath) { + ofstream file; + file.open(filePath.c_str()); + if (!file.is_open()) { + string error("[ERROR] Cannot open file "); + error += filePath; + error += " for writting."; + throw DTRException(error); + } + // checks before do anything + if (_rules.size() == 0) { + throw DTRException("[ERROR] Cannot writeToFile since no rule is defined!"); + } + + file << "" << endl + << " " << endl; + + for (size_t i = 0 ; i < _rules.size() ; i++) { + Rule* rule = _rules[i]; + if (dynamic_cast(rule)) { + file << " getName().getString() << "\" "; + } else { + file << " getName().getString() << "\" "; + } + if (rule->getType() != Name("")) { + file << "type=\"" << rule->getType().getString() << "\" "; + } + if (rule->getLayer1() != Name("")) { + if (rule->getLayer2() != Name("")) { + file << "layer1=\"" << rule->getLayer1().getString() << "\" layer2=\"" << rule->getLayer2().getString() << "\" "; + } else { + file << "layer=\"" << rule->getLayer1().getString() << "\" "; + } + } + file << "value=\"" << rule->getValue() << "\" ref=\"" << rule->getRef().getString() << "\"/>" << endl; + } + file << " " << endl + << "" << endl; + file.close(); + return true; +} + +} + diff --git a/vlsisapd/dtr/src/io/dtr/DTRException.h b/vlsisapd/dtr/src/io/dtr/DTRException.h new file mode 100644 index 00000000..a597b513 --- /dev/null +++ b/vlsisapd/dtr/src/io/dtr/DTRException.h @@ -0,0 +1,28 @@ +/* + * DTRException.h + * DTR + * + * Created by damien dupuis on 01/04/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __DTR_EXCEPTION_H__ +#define __DTR_EXCEPTION_H__ + +#include +#include + +namespace DTR { +class DTRException { + public: + DTRException(const std::string& what) throw() : _what(what) {} + virtual const char* what() const throw() { return _what.c_str(); } + virtual ~DTRException() throw() {} + + private: + std::string _what; +}; +} // namespace +#endif + diff --git a/vlsisapd/dtr/src/io/dtr/Name.h b/vlsisapd/dtr/src/io/dtr/Name.h new file mode 100644 index 00000000..30e2bc7f --- /dev/null +++ b/vlsisapd/dtr/src/io/dtr/Name.h @@ -0,0 +1,49 @@ +/* + * Name.h + * DTR + * + * Created by damien dupuis on 01/04/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __DTR_NAME_H__ +#define __DTR_NAME_H__ + +#include +#include + +#include "io/dtr/DTRException.h" + +namespace DTR { +class Name { + public: + Name(std::string); + Name(const char*); + + bool operator==(const Name&); + bool operator==(const std::string&); + bool operator!=(const Name&); + bool operator!=(const std::string&); + bool operator<(const Name) const; + + inline const std::string& getString() const; + + private: + unsigned long _id; + const std::string *_str; + + static std::map _dict; + static unsigned long _globalId; +}; + +inline const std::string& Name::getString() const{ + if (!_str) { + throw DTRException("[ERROR] Name object has no string"); + } + return *_str; +} + +} // namespace +#endif + diff --git a/vlsisapd/dtr/src/io/dtr/Rules.h b/vlsisapd/dtr/src/io/dtr/Rules.h new file mode 100644 index 00000000..6e365cb8 --- /dev/null +++ b/vlsisapd/dtr/src/io/dtr/Rules.h @@ -0,0 +1,56 @@ +/* + * Rules.h + * DTR + * + * Created by damien dupuis on 01/04/10. + * Copyright 2010 UPMC / LIP6 All rights reserved. + * + */ + +#ifndef __DTR_RULES_H__ +#define __DTR_RULES_H__ + +namespace DTR { +class Rule { + public: + Rule(Name name, double value, Name ref, Name layer1, Name layer2) + : _name(name), _type(Name("")), _value(value), _ref(ref), _layer1(layer1), _layer2(layer2) {}; + + // accessors + inline Name getName(); + inline Name getType(); + inline double getValue(); + inline Name getRef(); + inline Name getLayer1(); + virtual inline Name getLayer2(); // add virtual so the Rule object is polymorphic + + // modifiers + inline void setType(Name); + + // members + private: + Name _name; + Name _type; + double _value; + Name _ref; + Name _layer1; + Name _layer2; +}; + +class ARule : public Rule { + public: + ARule(Name name, double value, Name ref, Name layer1, Name layer2) + : Rule(name, value, ref, layer1, layer2) {}; +}; + +inline Name Rule::getName() { return _name; }; +inline Name Rule::getType() { return _type; }; +inline double Rule::getValue() { return _value; }; +inline Name Rule::getRef() { return _ref; }; +inline Name Rule::getLayer1() { return _layer1; }; +inline Name Rule::getLayer2() { return _layer2; }; + +inline void Rule::setType(Name type) { _type = type; }; +} // namespace DTR +#endif + diff --git a/vlsisapd/dtr/src/io/dtr/Techno.h b/vlsisapd/dtr/src/io/dtr/Techno.h new file mode 100644 index 00000000..93ca01ed --- /dev/null +++ b/vlsisapd/dtr/src/io/dtr/Techno.h @@ -0,0 +1,50 @@ +/* + * Techno.h + * DTR + * + * Created by damien dupuis on 01/04/10. + * Copyright 2010 UPMC / LIP6 All rights reserved. + * + */ + +#ifndef __DTR_TECHNO_H__ +#define __DTR_TECHNO_H__ + +#include + +#include +#include + +#include "io/dtr/Name.h" + +namespace DTR { +class Rule; +class ARule; +class Techno { + public: + Techno(Name name, Name unit); + + inline Name getName(); + inline Name getUnit(); + inline std::vector& getRules(); + + Rule* addRule (Name name, double value, Name ref, Name layer1=Name(""), Name layer2=Name("")); + ARule* addARule(Name name, double value, Name ref, Name layer1 , Name layer2); + + double getValue(Name type, Name layer1=Name(""), Name layer2=Name("")); + + bool writeToFile(std::string filePath); + static Techno* readFromFile(const std::string filePath); + + Name _name; + Name _unit; + std::vector _rules; +}; + +inline Name Techno::getName() { return _name; }; +inline Name Techno::getUnit() { return _unit; }; +inline std::vector& Techno::getRules() { return _rules; }; + +} // namespace DTR +#endif +