diff --git a/vlsisapd/openChams/CMakeLists.txt b/vlsisapd/openChams/CMakeLists.txt index 515100d3..1865776c 100644 --- a/vlsisapd/openChams/CMakeLists.txt +++ b/vlsisapd/openChams/CMakeLists.txt @@ -1,7 +1,7 @@ INCLUDE_DIRECTORIES(${CHAMS_SOURCE_DIR}/openChams ${LIBXML2_INCLUDE_DIR}) -SET ( includes Circuit.h Netlist.h Instance.h Net.h Name.h Parameters.h ) -SET ( cpps Circuit.cpp Netlist.cpp Instance.cpp Net.cpp Name.cpp Parameters.cpp ) +SET ( includes Circuit.h Netlist.h Instance.h Net.h Name.h Parameters.h Schematic.h OpenChamsException.h ) +SET ( cpps Circuit.cpp Netlist.cpp Instance.cpp Net.cpp Name.cpp Parameters.cpp Schematic.cpp ) ADD_LIBRARY(openChams SHARED ${cpps}) diff --git a/vlsisapd/openChams/Circuit.cpp b/vlsisapd/openChams/Circuit.cpp index af0dc771..5cbefdad 100644 --- a/vlsisapd/openChams/Circuit.cpp +++ b/vlsisapd/openChams/Circuit.cpp @@ -11,9 +11,11 @@ #include #include #include +#include using namespace std; #include "Circuit.h" +#include "OpenChamsException.h" namespace { template T getValue(xmlChar* str) { @@ -31,9 +33,42 @@ static bool readCircuitParametersDone = false; static bool readNetListDone = false; static bool readInstancesDone = false; static bool readNetsDone = false; +static bool readSchematicDone = false; -Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno) {} +Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL) { + readCircuitParametersDone = false; + readNetListDone = false; + readInstancesDone = false; + readNetsDone = false; + readSchematicDone = false; +} +void Circuit::check_uppercase(string& str, vector& compares, string message) { + transform(str.begin(), str.end(), str.begin(), ::toupper); + bool equal = false; + for (size_t i = 0 ; i < compares.size() ; i++) { + if (str == compares[i]) { + equal = true; + } + } + if (!equal) { + throw OpenChamsException(message); + } +} + +void Circuit::check_lowercase(string& str, vector& compares, string message) { + transform(str.begin(), str.end(), str.begin(), ::tolower); + bool equal = false; + for (size_t i = 0 ; i < compares.size() ; i++) { + if (str == compares[i]) { + equal = true; + } + } + if (!equal) { + throw OpenChamsException(message); + } +} + Name Circuit::readParameter(xmlNode* node, double& value) { xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* valueC = xmlGetProp(node, (xmlChar*)"value"); @@ -42,8 +77,8 @@ Name Circuit::readParameter(xmlNode* node, double& value) { value = ::getValue(valueC); return name; } else { - cerr << "[ERROR] 'parameter' node must have 'name' and 'value' properties." << endl; - return Name(""); + throw OpenChamsException("[ERROR] 'parameter' node must have 'name' and 'value' properties."); + //return Name(""); } } @@ -53,8 +88,8 @@ Name Circuit::readConnector(xmlNode* node) { Name name((const char*)connectorNameC); return name; } else { - cerr << "[ERROR] 'connector' node must have 'name' property." << endl; - return Name(""); + throw OpenChamsException("[ERROR] 'connector' node must have 'name' property."); + //return Name(""); } } @@ -126,15 +161,24 @@ Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) { xmlChar* iNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* iModelC = xmlGetProp(node, (xmlChar*)"model"); xmlChar* iMOSC = xmlGetProp(node, (xmlChar*)"mostype"); + xmlChar* iSBCC = xmlGetProp(node, (xmlChar*)"sourceBulkConnected"); Instance* inst = NULL; - if (iNameC && iModelC && iMOSC) { + if (iNameC && iModelC && iMOSC && iSBCC) { Name instanceName((const char*)iNameC); Name modelName((const char*)iModelC); - Name mosName((const char*)iMOSC); - inst = new Instance(instanceName, modelName, mosName, netlist); + string mosStr((const char*)iMOSC); + string mosComp[2] = {"NMOS", "PMOS"}; + vector mosComps (mosComp, mosComp+2); + check_uppercase(mosStr, mosComps, "[ERROR] In 'instance', 'mostype' must be 'NMOS' or 'PMOS'."); + string sourceBulkStr((const char*)iSBCC); + string sbcComp[4] = {"true", "false", "on", "off"}; + vector sbcComps(sbcComp, sbcComp+4); + check_lowercase(sourceBulkStr, sbcComps, "[ERROR] In 'instance', 'sourceBulkConnected' must 'true', 'false', 'on' or 'off'."); + bool sourceBulkConnected = ((sourceBulkStr == "true") || (sourceBulkStr == "on")) ? true : false; + inst = new Instance(instanceName, modelName, Name(mosStr), sourceBulkConnected, netlist); } else { - cerr << "[ERROR] 'instance' node must have 'name', 'model' and 'mos' properties." << endl; - return inst; + throw OpenChamsException("[ERROR] 'instance' node must have 'name', 'model', 'mostype' and 'sourceBulkConnected' properties."); + //return inst; } xmlNode* child = node->children; @@ -205,14 +249,20 @@ Net* Circuit::readNet(xmlNode* node, Netlist* netlist) { Net* net = NULL; if (nNameC && nTypeC && nExternC) { Name netName((const char*)nNameC); - Name typeName((const char*)nTypeC); + string typeStr((const char*)nTypeC); + string typeComp[3] = {"power", "ground", "logical"}; + vector typeComps(typeComp, typeComp+3); + check_lowercase(typeStr, typeComps, "[ERROR] In 'net', 'type' must be 'power', 'ground' or 'logical'."); string externStr((const char*)nExternC); - bool isExternal = (externStr == "True") ? true : false; - net = new Net(netName, typeName, isExternal, netlist); + string extComp[4] = {"true", "false", "on", "off"}; + vector extComps(extComp, extComp+4); + check_lowercase(externStr, extComps, "[ERROR] In 'net', 'isExternal' must be 'true', 'false', 'on' or 'off'."); + bool isExternal = ((externStr == "true") || (externStr == "on")) ? true : false; + net = new Net(netName, Name(typeStr), isExternal, netlist); netlist->addNet(net); } else { - cerr << "[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties." << endl; - return net; + throw OpenChamsException("[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties."); + //return net; } xmlNode* child = node->children; @@ -237,23 +287,77 @@ void Circuit::readNetConnector(xmlNode* node, Net* net) { Name cName((const char*)connectorNameC); Instance* inst = net->getNetlist()->getInstance(iName); if (!inst) { - cerr << "[ERROR] no instance named \"" << iName.getString() << "\" in connector of net \"" << net->getName().getString() << "\"." << endl; - return; + string error("[ERROR] no instance named \""); + error += iName.getString(); + error += "\" in connector of net \""; + error += net->getName().getString(); + error += "\"."; + throw OpenChamsException(error); + //return; } inst->connect(cName, net->getName()); net->connectTo(iName, cName); } else { - cerr << "[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)." << endl; + throw OpenChamsException("[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)."); } } -Circuit* Circuit::readFromFile(string filePath) { +void Circuit::readSchematic(xmlNode* node) { + if (readSchematicDone) { + cerr << "[WARNING] Only one 'schematic' node is allowed in circuit, others will be ignored." << endl; + return; + } + xmlChar* zoomC = xmlGetProp(node, (xmlChar*)"zoom"); + double zoom = 1.0; + if (zoomC) { + zoom = ::getValue(zoomC); + } else { + throw OpenChamsException("[ERROR] 'schematic' node must have 'zoom' property."); + } + + Schematic* schematic = new Schematic(this, zoom); + xmlNode* child = node->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstanceSchematic(node, schematic); + } else { + cerr << "[WARNING] Only 'instance' nodes are allowed in 'schematic', others will be ignored." << endl; + } + } + } + readSchematicDone = true; + _schematic = schematic; +} + +void Circuit::readInstanceSchematic(xmlNode* node, Schematic* schematic) { + xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); + xmlChar* xC = xmlGetProp(node, (xmlChar*)"x"); + xmlChar* yC = xmlGetProp(node, (xmlChar*)"y"); + xmlChar* symC = xmlGetProp(node, (xmlChar*)"sym"); + if (nameC && xC && yC && symC) { + Name iName((const char*)nameC); + double x = ::getValue(xC); + double y = ::getValue(yC); + string symStr((const char*)symC); + string symComp[8] = {"ID", "R1", "R2", "R3", "MX", "XR", "MY", "YR"}; + vector symComps (symComp, symComp+8); + check_uppercase(symStr, symComps, "[ERROR] In 'schematic/instance', 'sym' must be 'ID', 'R1', 'R2', 'R3', 'MX', 'XR', 'MY' or 'YR'."); + schematic->addInstance(iName, x, y, Name(symStr)); + } else { + throw OpenChamsException("[ERROR] 'instance' node in 'schematic' must have 'name', 'x', 'y' and 'sym' properties."); + } +} + +Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; Circuit* cir = NULL; xmlDoc* doc = xmlReadFile(filePath.c_str(), NULL, 0); if (doc == NULL) { - cerr << "[ERROR] Failed to parse: " << filePath << endl; - return NULL; + string error ("[ERROR] Failed to parse: "); + error += filePath; + throw OpenChamsException(error); + //return NULL; } xmlNode* rootElement = xmlDocGetRootElement(doc); if (rootElement->type == XML_ELEMENT_NODE && xmlStrEqual(rootElement->name, (xmlChar*)"circuit")) { @@ -265,7 +369,7 @@ Circuit* Circuit::readFromFile(string filePath) { Name technoName ((const char*)technoNameC); cir = new Circuit(circuitName, technoName); } else { - cerr << "[ERROR] 'circuit' node must have 'name' and 'techno' properties." << endl; + throw OpenChamsException("[ERROR] 'circuit' node must have 'name' and 'techno' properties."); return NULL; } @@ -279,9 +383,15 @@ Circuit* Circuit::readFromFile(string filePath) { if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { cir->readNetList(node); } + if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { + cir->readSchematic(node); + } } } } + if (!readNetListDone) { + throw OpenChamsException("[ERROR] no section was found in parsed file !"); + } return cir; } @@ -290,45 +400,49 @@ bool Circuit::writeToFile(string filePath) { file.open(filePath.c_str()); // checks before do anything if (!_netlist) { - cerr << "[ERROR] Cannot writeToFile since no netlist is defined !" << endl; - return false; + throw OpenChamsException("[ERROR] Cannot writeToFile since no netlist is defined !"); + //return false; } if (_netlist->hasNoInstances()) { - cerr << "[ERROR] Cannot writeToFile since no instance is defined in netlist !" << endl; - return false; + throw OpenChamsException("[ERROR] Cannot writeToFile since no instance is defined in netlist !"); + //return false; } if (_netlist->hasNoNets()) { - cerr << "[ERROR] Cannot writeToFile since no net is defined in netlist !" << endl; - return false; + throw OpenChamsException("[ERROR] Cannot writeToFile since no net is defined in netlist !"); + //return false; } file << "" << endl << "" << endl; if (!_params.isEmpty()) { file << " " << endl; - for (map::iterator it = _params.getFirstIt() ; it != _params.getLastIt() ; ++it) { + for (map::const_iterator it = _params.getValues().begin() ; it != _params.getValues().end() ; ++it) { file << " " << endl; } file << " " << endl; } file << " " << endl << " " << endl; - for (vector::iterator it = _netlist->getFirstInstanceIt() ; it != _netlist->getLastInstanceIt() ; ++it) { + for (vector::const_iterator it = _netlist->getInstances().begin() ; it != _netlist->getInstances().end() ; ++it) { Instance* inst = (*it); if (inst->hasNoConnectors()) { - cerr << "[ERROR] Cannot writeToFile since instance (" << inst->getName().getString() << ") has no connectors !" << endl; - return false; + string error("[ERROR] Cannot writeToFile since instance ("); + error += inst->getName().getString(); + error += ") has no connectors !"; + throw OpenChamsException(error); + //return false; } - file << " getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\">" << endl; + string sourceBulkStr = (inst->isSourceBulkConnected()) ? "True" : "False"; + file << " getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\">" << endl; file << " " << endl; - for (map::iterator it = inst->getFirstConnectorIt() ; it != inst->getLastConnectorIt() ; ++it) { + for (map::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { file << " " << endl; } file << " " << endl; if (!inst->getParameters().isEmpty()) { Parameters params = inst->getParameters(); file << " " << endl; - for (map::iterator it = params.getFirstIt() ; it != params.getLastIt() ; ++it) { + for (map::const_iterator it = params.getValues().begin() ; it != params.getValues().end() ; ++it) { file << " " << endl; } file << " " << endl; @@ -337,21 +451,32 @@ bool Circuit::writeToFile(string filePath) { } file << " " << endl << " " << endl; - for (vector::iterator it = _netlist->getFirstNetIt() ; it != _netlist->getLastNetIt() ; ++it) { + for (vector::const_iterator it = _netlist->getNets().begin() ; it != _netlist->getNets().end() ; ++it) { Net* net = (*it); if (net->hasNoConnectors()) { - cerr << "[ERROR] Cannot writeToFile since net (" << net->getName().getString() << ") has no connectors !" << endl; - return false; + string error("[ERROR] Cannot writeToFile since net ("); + error += net->getName().getString(); + error += ") has no connectors !"; + throw OpenChamsException(error); + //return false; } string externStr = (net->isExternal()) ? "True" : "False"; file << " getName().getString() << "\" type=\"" << net->getType().getString() << "\" isExternal=\"" << externStr << "\">" << endl; - for (vector >::iterator it = net->getFirstConnectionIt() ; it != net->getLastConnectionIt() ; ++it) { + for (vector >::const_iterator it = net->getConnections().begin() ; it != net->getConnections().end() ; ++it) { file << " " << endl; } file << " " << endl; } file << " " << endl; file << " " << endl; + if (_schematic && !_schematic->hasNoInstances()) { + file << " getZoom() << "\">" << endl; + for (map::const_iterator it = _schematic->getInstances().begin() ; it != _schematic->getInstances().end(); ++it ) { + Schematic::Infos* infos = (*it).second; + file << " getX() << "\" y=\"" << infos->getY() << "\" sym=\"" << infos->getSymetry().getString() << "\"/>" << endl; + } + file << " " << endl; + } file << "" << endl; file.close(); return true; diff --git a/vlsisapd/openChams/Circuit.h b/vlsisapd/openChams/Circuit.h index 2fb57d80..5c194c65 100644 --- a/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/openChams/Circuit.h @@ -18,19 +18,22 @@ #include "Netlist.h" #include "Instance.h" #include "Net.h" +#include "Schematic.h" namespace OpenChams { class Circuit { public: Circuit(Name name, Name techno); - inline Name getName(); - inline Name getTechno(); - inline double getValue(Name); - inline void addParameter(Name, double); + inline Name getName(); + inline Name getTechno(); + inline double getValue(Name); + inline Netlist* getNetlist(); + inline Schematic* getSchematic(); + inline void addParameter(Name, double); bool writeToFile(string filePath); - static Circuit* readFromFile(string filePath); + static Circuit* readFromFile(const string filePath); private: Name readParameter(xmlNode*, double&); @@ -44,18 +47,25 @@ class Circuit { void readNets(xmlNode*, Netlist*); Net* readNet (xmlNode*, Netlist*); void readNetConnector(xmlNode*, Net*); + void readSchematic(xmlNode*); + void readInstanceSchematic(xmlNode*, Schematic*); + void check_uppercase(string& str, vector& compares, string message); + void check_lowercase(string& str, vector& compares, string message); Name _name; Name _techno; Parameters _params; Netlist* _netlist; + Schematic* _schematic; }; -inline Name Circuit::getName() { return _name; } -inline Name Circuit::getTechno() { return _techno; } -inline double Circuit::getValue(Name name) { return _params.getValue(name); } -inline void Circuit::addParameter(Name name, double value) { _params.addParameter(name, value); } +inline Name Circuit::getName() { return _name; } +inline Name Circuit::getTechno() { return _techno; } +inline double Circuit::getValue(Name name) { return _params.getValue(name); } +inline Netlist* Circuit::getNetlist() { return _netlist; }; +inline Schematic* Circuit::getSchematic() { return _schematic; }; +inline void Circuit::addParameter(Name name, double value) { _params.addParameter(name, value); } } // namespace IO diff --git a/vlsisapd/openChams/Instance.cpp b/vlsisapd/openChams/Instance.cpp index b8b0a5a9..c7fae05f 100644 --- a/vlsisapd/openChams/Instance.cpp +++ b/vlsisapd/openChams/Instance.cpp @@ -13,12 +13,14 @@ using namespace std; #include "Instance.h" #include "Netlist.h" #include "Net.h" +#include "OpenChamsException.h" namespace OpenChams { -Instance::Instance(Name name, Name model, Name mosType, Netlist* netlist) +Instance::Instance(Name name, Name model, Name mosType, bool sourceBulkConnected, Netlist* netlist) : _name(name) , _model(model) , _mosType(mosType) + , _sourceBulkConnected(sourceBulkConnected) , _netlist(netlist) {} void Instance::addConnector(Name name) { @@ -26,8 +28,12 @@ void Instance::addConnector(Name name) { map::iterator it = _netMap.find(name); if (it == _netMap.end()) _netMap[name] = NULL; - else - cerr << "[ERROR] The same instance cannot have several connectors with same name (" << name.getString() << ")." << endl; + else { + string error("[ERROR] The same instance cannot have several connectors with same name ("); + error += name.getString(); + error += ")."; + throw OpenChamsException(error); + } } void Instance::connect(Name connectorName, Name netName) { @@ -37,13 +43,20 @@ void Instance::connect(Name connectorName, Name netName) { map::iterator it = _netMap.find(connectorName); if (it != _netMap.end()) { Net* net = _netlist->getNet(netName); - if (!net) - cerr << "[ERROR] While connecting instance : net (" << netName.getString() << ") does not exist." << endl; + if (!net) { + string error("[ERROR] While connecting instance : net ("); + error += netName.getString(); + error += ") does not exist."; + throw OpenChamsException(error); + } else _netMap[connectorName] = net; } - else - cerr << "[ERROR] While connecting instance : connector (" << connectorName.getString() << ") does not exist." << endl; + else { + string error("[ERROR] While connecting instance : connector ("); + error += connectorName.getString(); + error += ") does not exist."; + throw OpenChamsException(error); + } } -} - +} \ No newline at end of file diff --git a/vlsisapd/openChams/Instance.h b/vlsisapd/openChams/Instance.h index 946daef1..379ba863 100644 --- a/vlsisapd/openChams/Instance.h +++ b/vlsisapd/openChams/Instance.h @@ -10,9 +10,7 @@ #ifndef __OPENCHAMS_INSTANCE_H__ #define __OPENCHAMS_INSTANCE_H__ -#include #include -using namespace std; #include "Name.h" #include "Parameters.h" @@ -22,7 +20,7 @@ class Netlist; class Net; class Instance { public: - Instance(Name name, Name model, Name mosType, Netlist*); + Instance(Name name, Name model, Name mosType, bool, Netlist*); void addConnector(Name); void connect(Name connectorName, Name netName); @@ -33,29 +31,34 @@ class Instance { inline Name getName(); inline Name getModel(); inline Name getMosType(); + inline bool isSourceBulkConnected(); inline Parameters getParameters(); // pour parcourir les connecteurs inline bool hasNoConnectors(); - inline map::iterator getFirstConnectorIt(); - inline map::iterator getLastConnectorIt(); + //inline map::iterator getFirstConnectorIt(); + //inline map::iterator getLastConnectorIt(); + inline const std::map& getConnectors(); -private: + private: Name _name; Name _model; Name _mosType; + bool _sourceBulkConnected; Netlist* _netlist; Parameters _params; - map _netMap; //map associant nom de connecteur a un net + std::map _netMap; //map associant nom de connecteur a un net }; inline void Instance::addParameter(Name name, double value) { _params.addParameter(name, value); }; inline Name Instance::getName() { return _name; }; inline Name Instance::getModel() { return _model; }; inline Name Instance::getMosType() { return _mosType; }; +inline bool Instance::isSourceBulkConnected() { return _sourceBulkConnected; }; inline Parameters Instance::getParameters() { return _params; }; inline bool Instance::hasNoConnectors() { return (_netMap.size() == 0)? true : false; }; -inline map::iterator Instance::getFirstConnectorIt() { return _netMap.begin(); }; -inline map::iterator Instance::getLastConnectorIt() { return _netMap.end(); }; +//inline map::iterator Instance::getFirstConnectorIt() { return _netMap.begin(); }; +//inline map::iterator Instance::getLastConnectorIt() { return _netMap.end(); }; +inline const std::map& Instance::getConnectors() { return _netMap; }; } // namespace #endif diff --git a/vlsisapd/openChams/Name.cpp b/vlsisapd/openChams/Name.cpp index 6aabb04c..dcd973a8 100644 --- a/vlsisapd/openChams/Name.cpp +++ b/vlsisapd/openChams/Name.cpp @@ -7,13 +7,15 @@ * */ +using namespace std; + #include "Name.h" namespace OpenChams { unsigned long Name::_globalId = 0; map Name::_dict; -Name::Name(string str) { +Name::Name(string str) : _str(NULL) { map::iterator it = _dict.find(str); if (it != _dict.end()) { _id = (*it).second; @@ -25,7 +27,7 @@ Name::Name(string str) { } } -Name::Name(const char* c) { +Name::Name(const char* c) : _str(NULL) { string str(c); map::iterator it = _dict.find(str); if (it != _dict.end()) { diff --git a/vlsisapd/openChams/Name.h b/vlsisapd/openChams/Name.h index b3a63a5b..bad4d10d 100644 --- a/vlsisapd/openChams/Name.h +++ b/vlsisapd/openChams/Name.h @@ -12,33 +12,36 @@ #include #include -using namespace std; + +#include "OpenChamsException.h" namespace OpenChams { class Name { public: - Name(string); - Name(const char*); + Name(std::string); + Name(const char*); - bool operator==(const Name&); - bool operator==(const string&); - bool operator<(const Name) const; + bool operator==(const Name&); + bool operator==(const std::string&); + bool operator<(const Name) const; - inline const string& getString() const; + inline const std::string& getString() const; private: - unsigned long _id; - const string *_str; + unsigned long _id; + const std::string *_str; - static map _dict; - static unsigned long _globalId; + static std::map _dict; + static unsigned long _globalId; }; -const string& Name::getString() const{ +inline const std::string& Name::getString() const{ + if (!_str) { + throw OpenChamsException("[ERROR] Name object has no string"); + } return *_str; } } // namespace - #endif diff --git a/vlsisapd/openChams/Net.cpp b/vlsisapd/openChams/Net.cpp index ede61efa..5cad40c4 100644 --- a/vlsisapd/openChams/Net.cpp +++ b/vlsisapd/openChams/Net.cpp @@ -7,6 +7,8 @@ * */ +using namespace std; + #include "Net.h" #include "Netlist.h" diff --git a/vlsisapd/openChams/Net.h b/vlsisapd/openChams/Net.h index 4d5cf7b2..e3252752 100644 --- a/vlsisapd/openChams/Net.h +++ b/vlsisapd/openChams/Net.h @@ -11,11 +11,9 @@ #define __OPENCHAMS_NET_H__ #include -using namespace std; #include "Name.h" #include "Instance.h" -//#include "Net.h" namespace OpenChams { class Netlist; @@ -30,15 +28,16 @@ class Net { inline bool isExternal(); inline Netlist* getNetlist(); inline bool hasNoConnectors(); - inline vector >::iterator getFirstConnectionIt(); - inline vector >::iterator getLastConnectionIt(); + //inline vector >::iterator getFirstConnectionIt(); + //inline vector >::iterator getLastConnectionIt(); + inline const std::vector >& getConnections(); private: Name _name; Name _typeName; bool _isExternal; Netlist* _netlist; - vector< pair > _connections; // + std::vector > _connections; // }; inline Name Net::getName() { return _name; }; @@ -46,9 +45,10 @@ inline Name Net::getType() { return _typeName; }; inline bool Net::isExternal() { return _isExternal; }; inline Netlist* Net::getNetlist() { return _netlist; }; inline bool Net::hasNoConnectors() { return (_connections.size() == 0)? true : false; }; -inline vector >::iterator Net::getFirstConnectionIt() { return _connections.begin();}; -inline vector >::iterator Net::getLastConnectionIt() { return _connections.end();}; - +//inline vector >::iterator Net::getFirstConnectionIt() { return _connections.begin();}; +//inline vector >::iterator Net::getLastConnectionIt() { return _connections.end();}; +inline const std::vector >& Net::getConnections() { return _connections; }; + } // namespace #endif diff --git a/vlsisapd/openChams/Netlist.cpp b/vlsisapd/openChams/Netlist.cpp index 4bb65299..bdcb4521 100644 --- a/vlsisapd/openChams/Netlist.cpp +++ b/vlsisapd/openChams/Netlist.cpp @@ -11,26 +11,35 @@ #include using namespace std; -#include "Netlist.h" +#include "NetList.h" #include "Circuit.h" +#include "OpenChamsException.h" namespace OpenChams { Netlist::Netlist(Circuit* circuit) : _circuit(circuit) {} void Netlist::addInstance(Instance* inst) { - vector::iterator it = find(_instances.begin(), _instances.end(), inst); - if (it != _instances.end()) - cerr << "[WARNING] Cannot add instance twice in netlist (" << inst->getName().getString() << ")." << endl; - else - _instances.push_back(inst); + for (vector::iterator it = _instances.begin() ; it != _instances.end() ; ++it) { + if ((*it)->getName() == inst->getName()) { + string error("[ERROR] Cannot define two instances with the same name in netlist ("); + error += inst->getName().getString(); + error += ")."; + throw OpenChamsException(error); + } + } + _instances.push_back(inst); } void Netlist::addNet(Net* net) { - vector::iterator it = find(_nets.begin(), _nets.end(), net); - if (it != _nets.end()) - cerr << "[WARNING] Cannot add net twice in netlist (" << net->getName().getString() << ")." << endl; - else - _nets.push_back(net); + for (vector::iterator it = _nets.begin() ; it != _nets.end() ; ++it ) { + if ((*it)->getName() == net->getName()) { + string error("[ERROR] Cannot define two nets with the same name in netlist ("); + error += net->getName().getString(); + error += ")."; + throw OpenChamsException(error); + } + } + _nets.push_back(net); } Instance* Netlist::getInstance(Name instanceName) { @@ -51,3 +60,4 @@ Net* Netlist::getNet(Name netName) { return NULL; } } // namespace + diff --git a/vlsisapd/openChams/Netlist.h b/vlsisapd/openChams/Netlist.h index d491b425..83fb1358 100644 --- a/vlsisapd/openChams/Netlist.h +++ b/vlsisapd/openChams/Netlist.h @@ -11,7 +11,6 @@ #define __OPENCHAMS_NETLIST_H__ #include -using namespace std; #include "Name.h" #include "Instance.h" @@ -32,23 +31,27 @@ class Netlist { //pour parcourir les vector inline bool hasNoInstances(); inline bool hasNoNets(); - inline vector::iterator getFirstInstanceIt(); - inline vector::iterator getLastInstanceIt(); - inline vector::iterator getFirstNetIt(); - inline vector::iterator getLastNetIt(); - + //inline vector::iterator getFirstInstanceIt(); + //inline vector::iterator getLastInstanceIt(); + //inline vector::iterator getFirstNetIt(); + //inline vector::iterator getLastNetIt(); + inline const std::vector& getInstances(); + inline const std::vector& getNets(); + private: Circuit* _circuit; - vector _instances; - vector _nets; + std::vector _instances; + std::vector _nets; }; -inline bool Netlist::hasNoInstances() { return (_instances.size() == 0)? true : false; } -inline bool Netlist::hasNoNets() { return (_nets.size() == 0)? true : false; } -inline vector::iterator Netlist::getFirstInstanceIt() { return _instances.begin(); } -inline vector::iterator Netlist::getLastInstanceIt() { return _instances.end(); } -inline vector::iterator Netlist::getFirstNetIt() { return _nets.begin(); } -inline vector::iterator Netlist::getLastNetIt() { return _nets.end(); } +inline bool Netlist::hasNoInstances() { return (_instances.size() == 0)? true : false; } +inline bool Netlist::hasNoNets() { return (_nets.size() == 0)? true : false; } +//inline vector::iterator Netlist::getFirstInstanceIt() { return _instances.begin(); } +//inline vector::iterator Netlist::getLastInstanceIt() { return _instances.end(); } +//inline vector::iterator Netlist::getFirstNetIt() { return _nets.begin(); } +//inline vector::iterator Netlist::getLastNetIt() { return _nets.end(); } +inline const std::vector& Netlist::getInstances() { return _instances; }; +inline const std::vector& Netlist::getNets() { return _nets; }; } // namespace #endif diff --git a/vlsisapd/openChams/OpenChamsException.h b/vlsisapd/openChams/OpenChamsException.h new file mode 100644 index 00000000..d3b422c7 --- /dev/null +++ b/vlsisapd/openChams/OpenChamsException.h @@ -0,0 +1,27 @@ +/* + * OpenChamsException.h + * openChams + * + * Created by damien dupuis on 20/01/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_EXCEPTION_NET_H__ +#define __OPENCHAMS_EXCEPTION_NET_H__ + +#include +#include + +namespace OpenChams { +class OpenChamsException { + public: + OpenChamsException(const std::string& what) throw() : _what(what) {} + virtual const char* what() const throw() { return _what.c_str(); } + virtual ~OpenChamsException() throw() {} + + private: + std::string _what; +}; +} // namespace +#endif \ No newline at end of file diff --git a/vlsisapd/openChams/Parameters.cpp b/vlsisapd/openChams/Parameters.cpp index 66345c7c..7f90a81b 100644 --- a/vlsisapd/openChams/Parameters.cpp +++ b/vlsisapd/openChams/Parameters.cpp @@ -11,13 +11,16 @@ using namespace std; #include "Parameters.h" +#include "OpenChamsException.h" namespace OpenChams { double Parameters::getValue(Name name) { map::iterator it = _params.find(name); if (it == _params.end()) { - cerr << "[ERROR] No parameters named " << name.getString() << endl; - return 0.0; + string error("[ERROR] No parameters named "); + error += name.getString(); + throw OpenChamsException(error); + //return 0.0; } return (*it).second; } @@ -25,8 +28,11 @@ double Parameters::getValue(Name name) { void Parameters::addParameter(Name name, double value) { map::iterator it = _params.find(name); if ( it != _params.end() ) { - cerr << "[ERROR] Cannot addParameter " << name.getString() << " because it already exists !" << endl; - return; + string error("[ERROR] Cannot addParameter "); + error += name.getString(); + error += " because it already exists !"; + throw OpenChamsException(error); + //return; } _params[name] = value; } diff --git a/vlsisapd/openChams/Parameters.h b/vlsisapd/openChams/Parameters.h index 544af749..d6d2a698 100644 --- a/vlsisapd/openChams/Parameters.h +++ b/vlsisapd/openChams/Parameters.h @@ -11,7 +11,6 @@ #define __OPENCHAMS_PARAMETERS_H__ #include -using namespace std; #include "Name.h" @@ -25,16 +24,18 @@ public: // pour parcourir la map : inline bool isEmpty(); - inline map::iterator getFirstIt(); - inline map::iterator getLastIt(); + //inline map::iterator getFirstIt(); + //inline map::iterator getLastIt(); + inline const std::map& getValues(); private: - map _params; + std::map _params; }; inline bool Parameters::isEmpty() { return (_params.size() == 0)? true : false; } -inline map::iterator Parameters::getFirstIt() { return _params.begin(); } -inline map::iterator Parameters::getLastIt() { return _params.end(); } +//inline map::iterator Parameters::getFirstIt() { return _params.begin(); } +//inline map::iterator Parameters::getLastIt() { return _params.end(); } +inline const std::map& Parameters::getValues() { return _params; }; } // namespace #endif diff --git a/vlsisapd/openChams/Schematic.cpp b/vlsisapd/openChams/Schematic.cpp new file mode 100644 index 00000000..ce938b2d --- /dev/null +++ b/vlsisapd/openChams/Schematic.cpp @@ -0,0 +1,35 @@ +/* + * SchematicInfos.cpp + * openChams + * + * Created by damien dupuis on 22/01/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +using namespace std; + +#include "Schematic.h" +#include "OpenChamsException.h" + +namespace OpenChams { +Schematic::Schematic(Circuit* circuit, double zoom) + : _circuit(circuit) + , _zoom(zoom) {} + +void Schematic::addInstance(Name instanceName, double x, double y, Name sym) { + map::iterator it = _instances.find(instanceName); + if (it != _instances.end()) { + string error("[ERROR] Cannot set same instance twice in 'schematic' ("); + error += instanceName.getString(); + error += ")."; + throw OpenChamsException(error); + } + _instances[instanceName] = new Schematic::Infos(x, y, sym); +} + +Schematic::Infos::Infos(double x, double y, Name sym) + : _x(x) + , _y(y) + , _sym(sym) {} +} // namespace diff --git a/vlsisapd/openChams/Schematic.h b/vlsisapd/openChams/Schematic.h new file mode 100644 index 00000000..eced02dd --- /dev/null +++ b/vlsisapd/openChams/Schematic.h @@ -0,0 +1,58 @@ +/* + * SchematicInfos.h + * openChams + * + * Created by damien dupuis on 22/01/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_SCHEMATIC_H__ +#define __OPENCHAMS_SCHEMATIC_H__ + +#include + +#include "Name.h" + +namespace OpenChams { +class Circuit; +class Schematic { + public: + class Infos { + public: + Infos(double x, double y, Name sym); + + inline double getX(); + inline double getY(); + inline Name getSymetry(); + + private: + double _x; + double _y; + Name _sym; + }; + public: + Schematic(Circuit*, double); + + void addInstance(Name instanceName, double x, double y, Name sym ); + + inline double getZoom(); + inline bool hasNoInstances(); + inline const std::map& getInstances(); + + private: + Circuit* _circuit; + double _zoom; + std::map _instances; +}; + +inline double Schematic::getZoom() { return _zoom; }; +inline bool Schematic::hasNoInstances() { return (_instances.size() == 0) ? true : false; }; +inline const std::map& Schematic::getInstances() { return _instances; }; + +inline double Schematic::Infos::getX() { return _x; }; +inline double Schematic::Infos::getY() { return _y; }; +inline Name Schematic::Infos::getSymetry() { return _sym; }; + +} // namespace +#endif \ No newline at end of file