diff --git a/vlsisapd/src/openChams/src/CMakeLists.txt b/vlsisapd/src/openChams/src/CMakeLists.txt index 683e91fd..8f4f73b6 100644 --- a/vlsisapd/src/openChams/src/CMakeLists.txt +++ b/vlsisapd/src/openChams/src/CMakeLists.txt @@ -1,16 +1,17 @@ -INCLUDE_DIRECTORIES(${VLSISAPD_SOURCE_DIR}/src/openChams/src ${LIBXML2_INCLUDE_DIR}) +INCLUDE_DIRECTORIES(${VLSISAPD_SOURCE_DIR}/src/openChams/src ${LIBXML2_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH}) -SET ( includes vlsisapd/openChams/Circuit.h - vlsisapd/openChams/Netlist.h - vlsisapd/openChams/Instance.h - vlsisapd/openChams/Net.h - vlsisapd/openChams/Name.h - vlsisapd/openChams/Operator.h - vlsisapd/openChams/Parameters.h - vlsisapd/openChams/Schematic.h - vlsisapd/openChams/Sizing.h - vlsisapd/openChams/Transistor.h - vlsisapd/openChams/OpenChamsException.h +SET ( hpps vlsisapd/openChams/Circuit.h + vlsisapd/openChams/Netlist.h + vlsisapd/openChams/Instance.h + vlsisapd/openChams/Net.h + vlsisapd/openChams/Name.h + vlsisapd/openChams/Operator.h + vlsisapd/openChams/Parameters.h + vlsisapd/openChams/Schematic.h + vlsisapd/openChams/SimulModel.h + vlsisapd/openChams/Sizing.h + vlsisapd/openChams/Transistor.h + vlsisapd/openChams/OpenChamsException.h ) SET ( cpps Circuit.cpp Netlist.cpp @@ -20,12 +21,24 @@ SET ( cpps Circuit.cpp Operator.cpp Parameters.cpp Schematic.cpp + SimulModel.cpp Sizing.cpp Transistor.cpp ) +SET ( pycpps PyOpenChams.cpp ${cpps}) ADD_LIBRARY(openChams ${cpps}) - +TARGET_LINK_LIBRARIES(openChams ${LIBXML2_LIBRARIES}) INSTALL(TARGETS openChams DESTINATION lib${LIB_SUFFIX} ) -INSTALL(FILES ${includes} DESTINATION include/vlsisapd/openChams) +IF(Boost_FOUND) + ADD_LIBRARY(pyOPENCHAMS MODULE ${pycpps}) + SET_TARGET_PROPERTIES(pyOPENCHAMS PROPERTIES + COMPILE_FLAGS "${COMPILE_FLAGS} -D__PYTHON_MODULE__=1" + PREFIX "" + ) + TARGET_LINK_LIBRARIES(pyOPENCHAMS openChams ${LIBXML2_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) + INSTALL(TARGETS pyOPENCHAMS DESTINATION ${PYTHON_SITE_PACKAGES}) +ENDIF(Boost_FOUND) + +INSTALL(FILES ${hpps} DESTINATION include/vlsisapd/openChams) diff --git a/vlsisapd/src/openChams/src/Circuit.cpp b/vlsisapd/src/openChams/src/Circuit.cpp index 5bddf0f1..68ad2cb9 100644 --- a/vlsisapd/src/openChams/src/Circuit.cpp +++ b/vlsisapd/src/openChams/src/Circuit.cpp @@ -19,6 +19,7 @@ using namespace std; #include "vlsisapd/openChams/Instance.h" #include "vlsisapd/openChams/Net.h" #include "vlsisapd/openChams/Schematic.h" +#include "vlsisapd/openChams/SimulModel.h" #include "vlsisapd/openChams/Sizing.h" #include "vlsisapd/openChams/Transistor.h" #include "vlsisapd/openChams/Operator.h" @@ -37,14 +38,16 @@ namespace { namespace OpenChams { static bool readCircuitParametersDone = false; -static bool readNetListDone = false; -static bool readInstancesDone = false; -static bool readNetsDone = false; -static bool readSchematicDone = false; -static bool readSizingDone = false; +static bool readSimulModelsDone = false; +static bool readNetListDone = false; +static bool readInstancesDone = false; +static bool readNetsDone = false; +static bool readSchematicDone = false; +static bool readSizingDone = false; Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL) { readCircuitParametersDone = false; + readSimulModelsDone = false; readNetListDone = false; readInstancesDone = false; readNetsDone = false; @@ -53,8 +56,8 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis } // COMPARISON FUNCTION // -bool ConnectionsSort(const pair& p1, const pair& p2) { - return p1.first < p2.first; +bool ConnectionsSort(const Net::Connection* c1, const Net::Connection* c2) { + return c1->getInstanceName() < c2->getInstanceName(); } bool InstanceNameSort(const Instance* i1, const Instance* i2) { @@ -92,6 +95,14 @@ void Circuit::check_lowercase(string& str, vector& compares, string mess } } +void Circuit::addSimulModel(unsigned id, SimulModel::Base base, SimulModel::Version version, std::string filePath) { + SimulModel* sim = new SimulModel(id, base, version, filePath); + map::iterator it = _simulModels.find(id); + if (it != _simulModels.end()) + throw OpenChamsException("[ERROR] Cannot define two SimulModels' models with the same ID."); + _simulModels[id] = sim; +} + Name Circuit::readParameter(xmlNode* node, double& value) { xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* valueC = xmlGetProp(node, (xmlChar*)"value"); @@ -156,6 +167,69 @@ void Circuit::readCircuitParameters(xmlNode* node) { readCircuitParametersDone = true; } +void Circuit::readSimulModels(xmlNode* node) { + if (readSimulModelsDone) { + cerr << "[WARNING] Only one 'simulModels' node is allowed in circuit, others will be ignored." << endl; + return; + } + if (node->type == XML_ELEMENT_NODE && node->children) { + for (xmlNode* modelNode = node->children ; modelNode ; modelNode = modelNode->next) { + if (modelNode->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(modelNode->name, (xmlChar*)"model")) { + xmlChar* mIdC = xmlGetProp(modelNode, (xmlChar*)"id"); + xmlChar* mBaseC = xmlGetProp(modelNode, (xmlChar*)"base"); + xmlChar* mVersionC = xmlGetProp(modelNode, (xmlChar*)"version"); + xmlChar* mFilePathC = xmlGetProp(modelNode, (xmlChar*)"filePath"); + if (mIdC && mBaseC && mVersionC && mFilePathC) { + unsigned id = ::getValue(mIdC); + SimulModel::Base base = SimulModel::BSIM3V3; + string mBase((const char*)mBaseC); + string baseComp[3] = { "BSIM3V3", "BSIM4", "PSP" }; + vector baseComps(baseComp, baseComp+3); + check_uppercase(mBase, baseComps, "[ERROR] SimulModels models' base property must be \"BSIM3V3\", \"BSIM4\" or \"PSP\"."); + if (mBase == "BSIM3V3") { + base = SimulModel::BSIM3V3; + } else if (mBase == "BSIM4") { + base = SimulModel::BSIM4; + } else if (mBase == "PSP") { + base = SimulModel::PSP; + } else { + throw OpenChamsException("[ERROR] SimulModels models' base property must be \"BSIM3V3\", \"BSIM4\" or \"PSP\" (check_uppercase should have filtered that)."); + return; + } + SimulModel::Version version = SimulModel::UNDEFINED; + string mVersion((const char*)mVersionC); + string verComp[4] = { "UNDEFINED", "SVT", "HVT", "LVT" }; + vector verComps(verComp, verComp+4); + check_uppercase(mVersion, verComps, "[ERROR] SimulModels model's version property must be \"UNDEFINED\", \"SVT\", \"HVT\" or \"LVT\"."); + if (mVersion == "UNDEFINED") { + version = SimulModel::UNDEFINED; + } else if (mVersion == "SVT") { + version = SimulModel::SVT; + } else if (mVersion == "HVT") { + version = SimulModel::HVT; + } else if (mVersion == "LVT") { + version = SimulModel::LVT; + } else { + throw OpenChamsException("[ERROR] SimulModels models' version property must be \"UNDEFINED\", \"SVT\", \"HVT\" or \"LVT\" (check_uppercase should have filtered that)."); + return; + } + string filePath((const char*)mFilePathC); + addSimulModel(id, base, version, filePath); + // Ce simuModel DOIT être rataché au circuit !!! + } else { + throw OpenChamsException("[ERROR] 'model' node must have 'id', 'base', 'version' and 'filePath' properties."); + } + } else { + cerr << "[WARNING] Only 'model' nodes are allowed under 'simulModels' node." << endl; + return; + } + } + } + } + readSimulModelsDone = true; +} + // NETLIST // void Circuit::readNetList(xmlNode* node) { if (readNetListDone) { @@ -189,9 +263,7 @@ void Circuit::readInstances(xmlNode* node, Netlist* netlist) { for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"instance")) { - Instance* inst =readInstance(node, netlist); - if (inst) - netlist->addInstance(inst); + readInstance(node, netlist); } else { cerr << "[WARNING] Only 'instance' nodes are allowed in 'instances', others will be ignored." << endl; } @@ -218,7 +290,7 @@ Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) { 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); + inst = netlist->addInstance(instanceName, modelName, Name(mosStr), sourceBulkConnected); } else { throw OpenChamsException("[ERROR] 'instance' node must have 'name', 'model', 'mostype' and 'sourceBulkConnected' properties."); //return inst; @@ -296,7 +368,7 @@ void Circuit::readTransistor(xmlNode* node, Instance* inst) { Transistor* trans = NULL; if (tNameC) { Name tName((const char*)tNameC); - trans = new Transistor(tName, inst); + trans = inst->addTransistor(tName); } else { throw OpenChamsException("[ERROR] 'transistor' node must have 'name' property."); //return inst; @@ -314,7 +386,6 @@ void Circuit::readTransistor(xmlNode* node, Instance* inst) { } } } - inst->addTransistor(trans); } void Circuit::readTransistorConnection(xmlNode* node, Transistor* trans) { @@ -372,8 +443,7 @@ Net* Circuit::readNet(xmlNode* node, Netlist* netlist) { 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); + net = netlist->addNet(netName, Name(typeStr), isExternal); } else { throw OpenChamsException("[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties."); //return net; @@ -385,7 +455,7 @@ Net* Circuit::readNet(xmlNode* node, Netlist* netlist) { if (xmlStrEqual(node->name, (xmlChar*)"connector")) { readNetConnector(node, net); } else { - cerr << "[WARNING] Only 'conector' nodes are allowed in 'net', others will be ignored." << endl; + cerr << "[WARNING] Only 'connector' nodes are allowed in 'net', others will be ignored." << endl; return NULL; } } @@ -602,15 +672,25 @@ Circuit* Circuit::readFromFile(const string filePath) { if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { cir->readCircuitParameters(node); } - if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { + else if (xmlStrEqual(node->name, (xmlChar*)"simulModels")) { + cir->readSimulModels(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { cir->readNetList(node); } - if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { + else if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { cir->readSchematic(node); } - if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { + else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { cir->readSizing(node); } + else { + string error("[ERROR] Unknown section "); + error += string((const char*)node->name); + error += " in circuit description."; + throw OpenChamsException(error); + return NULL; + } } } } @@ -620,6 +700,39 @@ Circuit* Circuit::readFromFile(const string filePath) { return cir; } +Netlist* Circuit::createNetlist() { + if (_netlist) + throw OpenChamsException("[ERROR] Cannot create two netlists in one circuit."); + + _netlist = new Netlist(this); + if (!_netlist) + throw OpenChamsException("[ERROR] Cannot create netlist."); + + return _netlist; +} + +Schematic* Circuit::createSchematic(double zoom) { + if (_schematic) + throw OpenChamsException("[ERROR] Cannot create two scheamtics in one circuit."); + + _schematic = new Schematic(this, zoom); + if (!_schematic) + throw OpenChamsException("[ERROR] Cannot create schematic."); + + return _schematic; +} + +Sizing* Circuit::createSizing() { + if (_sizing) + throw OpenChamsException("[ERROR] Cannot create two sizings in one circuit."); + + _sizing = new Sizing(this); + if (!_sizing) + throw OpenChamsException("[ERROR] Cannot create sizing."); + + return _sizing; +} + bool Circuit::writeToFile(string filePath) { ofstream file; file.open(filePath.c_str()); @@ -708,7 +821,7 @@ bool Circuit::writeToFile(string filePath) { sort(nets.begin(), nets.end(), NetNameSort); // sort based on nets' names for (vector::iterator it = nets.begin() ; it != nets.end() ; ++it) { Net* net = (*it); - if (net->hasNoConnectors()) { + if (net->hasNoConnections()) { string error("[ERROR] Cannot writeToFile since net ("); error += net->getName().getString(); error += ") has no connectors !"; @@ -717,10 +830,10 @@ bool Circuit::writeToFile(string filePath) { } string externStr = (net->isExternal()) ? "True" : "False"; file << " getName().getString() << "\" type=\"" << net->getType().getString() << "\" isExternal=\"" << externStr << "\">" << endl; - vector > connections = net->getConnections(); + vector connections = net->getConnections(); sort(connections.begin(), connections.end(), ConnectionsSort); - for (vector >::iterator it = connections.begin() ; it != connections.end() ; ++it) { - file << " " << endl; + for (vector::iterator it = connections.begin() ; it != connections.end() ; ++it) { + file << " getInstanceName().getString() << "\" name=\"" << (*it)->getConnectorName().getString() << "\"/>" << endl; } file << " " << endl; } @@ -730,7 +843,7 @@ bool Circuit::writeToFile(string filePath) { 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 << " getX() << "\" y=\"" << infos->getY() << "\" sym=\"" << infos->getSymmetry().getString() << "\"/>" << endl; } file << " " << endl; } diff --git a/vlsisapd/src/openChams/src/Instance.cpp b/vlsisapd/src/openChams/src/Instance.cpp index a0b51c68..2c239851 100644 --- a/vlsisapd/src/openChams/src/Instance.cpp +++ b/vlsisapd/src/openChams/src/Instance.cpp @@ -22,13 +22,17 @@ Instance::Instance(Name name, Name model, Name mosType, bool sourceBulkConnected , _model(model) , _mosType(mosType) , _sourceBulkConnected(sourceBulkConnected) - , _netlist(netlist) {} + , _netlist(netlist) + , _params() + , _netMap() + , _trans() {} void Instance::addConnector(Name name) { // si name n'est pas déjà présent dans la map on ajoute name, NULL (pas de net) map::iterator it = _netMap.find(name); - if (it == _netMap.end()) + if (it == _netMap.end()) { _netMap[name] = NULL; + } else { string error("[ERROR] The same instance cannot have several connectors with same name ("); error += name.getString(); @@ -60,5 +64,14 @@ void Instance::connect(Name connectorName, Name netName) { throw OpenChamsException(error); } } + +Transistor* Instance::addTransistor(Name name) { + Transistor* tr = new Transistor(name, this); + if (!tr) + throw OpenChamsException("[ERROR] Cannot create transistor."); + + _trans.push_back(tr); + return tr; +} } diff --git a/vlsisapd/src/openChams/src/Name.cpp b/vlsisapd/src/openChams/src/Name.cpp index bcf83ccc..20ee5e59 100644 --- a/vlsisapd/src/openChams/src/Name.cpp +++ b/vlsisapd/src/openChams/src/Name.cpp @@ -15,6 +15,18 @@ namespace OpenChams { unsigned long Name::_globalId = 0; map Name::_dict; +Name::Name() : _str(NULL) { + map::iterator it = _dict.find(""); + if (it != _dict.end()) { + _id = (*it).second; + _str = &((*it).first); + } else { + _id = _globalId++; + it = _dict.insert(_dict.begin(), make_pair("", _id)); + _str = &((*it).first); + } +} + Name::Name(string str) : _str(NULL) { map::iterator it = _dict.find(str); if (it != _dict.end()) { diff --git a/vlsisapd/src/openChams/src/Net.cpp b/vlsisapd/src/openChams/src/Net.cpp index 4a081200..3d588cb4 100644 --- a/vlsisapd/src/openChams/src/Net.cpp +++ b/vlsisapd/src/openChams/src/Net.cpp @@ -10,7 +10,9 @@ using namespace std; #include "vlsisapd/openChams/Net.h" +#include "vlsisapd/openChams/Instance.h" #include "vlsisapd/openChams/Netlist.h" +#include "vlsisapd/openChams/OpenChamsException.h" namespace OpenChams { Net::Net(Name netName, Name typeName, bool isExternal, Netlist* netlist) @@ -20,6 +22,19 @@ Net::Net(Name netName, Name typeName, bool isExternal, Netlist* netlist) , _netlist(netlist) {} void Net::connectTo(Name instanceName, Name connectorName) { - _connections.push_back(pair(instanceName, connectorName)); + _connections.push_back(new Net::Connection(instanceName, connectorName)); + Instance* inst = _netlist->getInstance(instanceName); + if (!inst) { + string error ("[ERROR] While connecting net "); + error += _name.getString(); + error += " to instance "; + error += instanceName.getString(); + error += ": instance does not exist in netlist !"; + throw OpenChamsException(error); + } else { + inst->connect(connectorName, _name); + } } + +Net::Connection::Connection(Name instanceName, Name connectorName) : _instanceName(instanceName), _connectorName(connectorName) {} } // namespace diff --git a/vlsisapd/src/openChams/src/Netlist.cpp b/vlsisapd/src/openChams/src/Netlist.cpp index 53b20a5e..22456553 100644 --- a/vlsisapd/src/openChams/src/Netlist.cpp +++ b/vlsisapd/src/openChams/src/Netlist.cpp @@ -20,28 +20,39 @@ using namespace std; namespace OpenChams { Netlist::Netlist(Circuit* circuit) : _circuit(circuit) {} -void Netlist::addInstance(Instance* inst) { +Instance* Netlist::addInstance(Name name, Name model, Name mosType, bool sourceBulkConnected) { for (vector::iterator it = _instances.begin() ; it != _instances.end() ; ++it) { - if ((*it)->getName() == inst->getName()) { + if ((*it)->getName() == name) { string error("[ERROR] Cannot define two instances with the same name in netlist ("); - error += inst->getName().getString(); + error += name.getString(); error += ")."; throw OpenChamsException(error); } } + Instance* inst = new Instance(name, model, mosType, sourceBulkConnected, this); + if (!inst) + throw OpenChamsException("[ERROR] Cannot creeate instance."); _instances.push_back(inst); + + return inst; } -void Netlist::addNet(Net* net) { +Net* Netlist::addNet(Name name, Name type, bool external) { for (vector::iterator it = _nets.begin() ; it != _nets.end() ; ++it ) { - if ((*it)->getName() == net->getName()) { + if ((*it)->getName() == name) { string error("[ERROR] Cannot define two nets with the same name in netlist ("); - error += net->getName().getString(); + error += name.getString(); error += ")."; throw OpenChamsException(error); } } + Net* net = new Net(name, type, external, this); + if (!net) + throw OpenChamsException("[ERROR] Cannot create net."); + _nets.push_back(net); + + return net; } Instance* Netlist::getInstance(Name instanceName) { diff --git a/vlsisapd/src/openChams/src/Operator.cpp b/vlsisapd/src/openChams/src/Operator.cpp index c52bd093..29716cf7 100644 --- a/vlsisapd/src/openChams/src/Operator.cpp +++ b/vlsisapd/src/openChams/src/Operator.cpp @@ -19,6 +19,10 @@ Operator::Operator(Name operatorName, Name simulModel, unsigned callOrder) , _simulModel(simulModel) , _callOrder(callOrder) {} +void Operator::addConstraint(Name paramName, Name ref, Name refParam) { + addConstraint(paramName, ref, refParam, 1.0); +} + void Operator::addConstraint(Name paramName, Name ref, Name refParam, double factor) { map::iterator it = _constraints.find(paramName); if (it != _constraints.end()) { @@ -30,6 +34,10 @@ void Operator::addConstraint(Name paramName, Name ref, Name refParam, double fac _constraints[paramName] = new Operator::Constraint(ref, refParam, factor); } +void Operator::addConstraint(Name paramName, Name refEquation) { + addConstraint(paramName, refEquation, 1.0); +} + void Operator::addConstraint(Name paramName, Name refEquation, double factor) { map::iterator it = _constraints.find(paramName); if (it != _constraints.end()) { diff --git a/vlsisapd/src/openChams/src/Parameters.cpp b/vlsisapd/src/openChams/src/Parameters.cpp index 1d2e2503..bae35477 100644 --- a/vlsisapd/src/openChams/src/Parameters.cpp +++ b/vlsisapd/src/openChams/src/Parameters.cpp @@ -26,6 +26,16 @@ double Parameters::getValue(Name name) { } return (*it).second; } + +std::string Parameters::getEqValue(Name name) { + map::iterator it = _paramsEq.find(name); + if (it == _paramsEq.end()) { + string error("[ERROR] No parameters named "); + error += name.getString(); + throw OpenChamsException(error); + } + return (*it).second; +} void Parameters::addParameter(Name name, double value) { map::iterator it = _params.find(name); diff --git a/vlsisapd/src/openChams/src/PyOpenChams.cpp b/vlsisapd/src/openChams/src/PyOpenChams.cpp new file mode 100644 index 00000000..755e0a7a --- /dev/null +++ b/vlsisapd/src/openChams/src/PyOpenChams.cpp @@ -0,0 +1,267 @@ +using namespace std; + +#include +#include +using namespace boost::python; + +#include "vlsisapd/openChams/Name.h" +#include "vlsisapd/openChams/Parameters.h" +#include "vlsisapd/openChams/Transistor.h" +#include "vlsisapd/openChams/Instance.h" +#include "vlsisapd/openChams/Net.h" +#include "vlsisapd/openChams/Netlist.h" +#include "vlsisapd/openChams/Schematic.h" +#include "vlsisapd/openChams/Operator.h" +#include "vlsisapd/openChams/SimulModel.h" +#include "vlsisapd/openChams/Sizing.h" +#include "vlsisapd/openChams/Circuit.h" +#include "vlsisapd/openChams/OpenChamsException.h" + +#include "vlsisapd/openChams/PySTLMapWrapper.h" + +namespace OpenChams { +void translator(OpenChamsException const& e) { + PyErr_SetString(PyExc_UserWarning, e.what()); +} + +BOOST_PYTHON_MODULE(pyOPENCHAMS) { + // class OpenChams::Name + class_("Name", init()) + .def(init<>()) + // accessors + .def("getString", &Name::getString, return_value_policy()) // return_value_policy because this method return a refenrce on string + .def("__repr__" , &Name::getString, return_value_policy()) // automatic print for Name object + // operators + .def(self == self) + .def(self == std::string()) + .def(self < self) + ; + + implicitly_convertible(); + + // map wrapping for OpenChams::Parameters + STL_MAP_WRAPPING(Name, double , "ValuesMap" ) + STL_MAP_WRAPPING(Name, std::string, "EquationsMap") + // class OpenChams::Parameters + class_("Parameters", init<>()) + // accessors + .def("getValue" , &Parameters::getValue ) + .def("getEqValue" , &Parameters::getEqValue) + .def("isEmpty" , &Parameters::isEmpty ) + // modifiers + .def("addParameter", static_cast(&Parameters::addParameter)) + .def("addParameter", static_cast(&Parameters::addParameter)) + // stl containers + .def("getValues" , &Parameters::getValues , return_value_policy()) + .def("getEqValues" , &Parameters::getEqValues, return_value_policy()) + ; + + { //this scope is used to define Base as a subenum of SimulModel + // class OpenChams::SimulModel + scope simMod = class_("SimulModel", init()) + // properties + .add_property("id" , &SimulModel::getId ) + .add_property("base" , &SimulModel::getBase ) + .add_property("version" , &SimulModel::getVersion ) + .add_property("filePath", &SimulModel::getFilePath) + ; + + enum_("Base") + .value("BSIM3V3", SimulModel::BSIM3V3) + .value("BSIM4" , SimulModel::BSIM4 ) + .value("PSP" , SimulModel::PSP ) + ; + + enum_("Version") + .value("UNDEFINED", SimulModel::UNDEFINED) + .value("SVT" , SimulModel::SVT ) + .value("HVT" , SimulModel::HVT ) + .value("LVT" , SimulModel::LVT ) + ; + } + + // class OpenChams::Transistor + class_("Transistor", init()) + // properties + .add_property("name" , &Transistor::getName , &Transistor::setName ) + .add_property("gate" , &Transistor::getGate , &Transistor::setGate ) + .add_property("source" , &Transistor::getSource , &Transistor::setSource) + .add_property("drain" , &Transistor::getDrain , &Transistor::setDrain ) + .add_property("bulk" , &Transistor::getBulk , &Transistor::setBulk ) + .add_property("parameters", &Transistor::getParameters ) // no setter => params will be readonly + // modifiers + .def("addParameter", static_cast(&Transistor::addParameter)) + .def("addParameter", static_cast(&Transistor::addParameter)) + ; + + // map wrapping and vector_indexing for OpenChams::Instance + STL_MAP_WRAPPING_PTR(Name, Net*, "ConnectorsMap") + + class_ >("TransistorsVector") + .def(vector_indexing_suite, true>()) + ; + // class OpenChams::Instance + class_("Instance", init()) + // properties + .add_property("name" , &Instance::getName ) + .add_property("model" , &Instance::getModel ) + .add_property("mosType" , &Instance::getMosType ) + .add_property("sourceBulkConnected", &Instance::isSourceBulkConnected) + .add_property("parameters" , &Instance::getParameters ) + .add_property("netlist" , make_function(&Instance::getNetlist ,return_value_policy())) //make_function since we need to specify a return value policy + // accessors + .def("hasNoConnectors" , &Instance::hasNoConnectors ) + .def("hasNoTransistors", &Instance::hasNoTransistors) + // modifiers + .def("addConnector" , &Instance::addConnector ) + .def("connect" , &Instance::connect ) + .def("addTransistor", &Instance::addTransistor, return_value_policy()) + .def("addParameter" , static_cast(&Transistor::addParameter)) + .def("addParameter" , static_cast(&Transistor::addParameter)) + // stl containers + .def("getConnectors" , &Instance::getConnectors , return_internal_reference<>()) + .def("getTransistors", &Instance::getTransistors, return_internal_reference<>()) + ; + + // vector_indexing for OpenChams::Net + class_ >("ConnectionsVector") + .def(vector_indexing_suite, true>()) + ; + { //this scope is used to define Connection as a subclass of Net + // class OpenChams::Net + scope netScope = class_("Net", init()) + // properties + .add_property("name" , &Net::getName ) + .add_property("type" , &Net::getType ) + .add_property("external", &Net::isExternal) + .add_property("netlist" , make_function(&Net::getNetlist, return_value_policy())) + // accessors + .def("hasNoConnections", &Net::hasNoConnections) + // modifiers + .def("connectTo" , &Net::connectTo ) + // stl containers + .def("getConnections", &Net::getConnections, return_internal_reference<>()) + ; + + // class OpenChams::Net::Connection + class_("Connection", init()) + .add_property("instanceName" , &Net::Connection::getInstanceName ) + .add_property("connectorName", &Net::Connection::getConnectorName) + ; + } // end netScope + + // vector_indexing for OpenChams::Netlist + class_ >("InstancesVector") + .def(vector_indexing_suite, true>()) + ; + class_ >("NetsVector") + .def(vector_indexing_suite, true>()) + ; + // class OpenChams::Netlist + class_("Netlist", init()) + // accessors + .def("hasNoInstances", &Netlist::hasNoInstances) + .def("hasNoNets" , &Netlist::hasNoNets ) + .def("getInstance" , make_function(&Netlist::getInstance , return_value_policy())) + .def("getNet" , make_function(&Netlist::getNet , return_value_policy())) + // modifiers + .def("addInstance", &Netlist::addInstance, return_value_policy()) + .def("addNet" , &Netlist::addNet , return_value_policy()) + // stl containers + .def("getInstances", &Netlist::getInstances, return_internal_reference<>()) + .def("getNets" , &Netlist::getNets , return_internal_reference<>()) + ; + + // map wrapping for OpenChams::Schematic + STL_MAP_WRAPPING_PTR(Name, Schematic::Infos*, "SchematicInstancesMap") + { // this scope is used to define Infos as a subclass of Schematic + // class OpenChams::Schematic + scope schematicScope = class_("Schematic", init()) + // properties + .add_property("zoom", &Schematic::getZoom) + // accessors + .def("hasNoInstances", &Schematic::hasNoInstances) + // modifiers + .def("addInstance", &Schematic::addInstance) + // stl containers + .def("getInstances", &Schematic::getInstances, return_internal_reference<>()) + ; + + // class OpenChams::Schematic::Infos + class_("Infos", init()) + .add_property("x" , &Schematic::Infos::getX ) + .add_property("y" , &Schematic::Infos::getY ) + .add_property("symmetry", &Schematic::Infos::getSymmetry) + ; + } // end schematicScope + + // map wrapping for OpenChams::Operator + STL_MAP_WRAPPING_PTR(Name, Operator::Constraint*, "ConstraintsMap") + { // this scope is used to define Constraint as a subclass of Operator + // class OpenChams::Operator + scope operatorScope = class_("Operator", init()) + // properties + .add_property("name" , &Operator::getName ) + .add_property("simulModel", &Operator::getSimulModel) + .add_property("callOrder" , &Operator::getCallOrder ) + // accessors + .def("hasNoConstraints", &Operator::hasNoConstraints) + // modifiers + .def("addConstraint", static_cast(&Operator::addConstraint)) + .def("addConstraint", static_cast(&Operator::addConstraint)) + .def("addConstraint", static_cast(&Operator::addConstraint)) + .def("addConstraint", static_cast(&Operator::addConstraint)) + // stl containers + .def("getConstraints", &Operator::getConstraints, return_internal_reference<>()) + ; + + // class OpenChams::Operator::Constraint + class_("Constraint", init()) + .add_property("ref" , &Operator::Constraint::getRef ) + .add_property("refParam", &Operator::Constraint::getRefParam) + .add_property("factor" , &Operator::Constraint::getFactor ) + ; + } // end operatorScope + + // map wrapping for OpenChams::Sizing + STL_MAP_WRAPPING_PTR(Name, Operator*, "OperatorsMap") + // class OpenChams::Sizing + class_("Sizing", init()) + // accessors + .def("hasNoEquations", &Sizing::hasNoEquations) + .def("hasNoOperators", &Sizing::hasNoOperators) + // modifiers + .def("addEquation", &Sizing::addEquation) + .def("addOperator", &Sizing::addOperator, return_value_policy()) + // stl containers + .def("getEquations", &Sizing::getEquations, return_internal_reference<>()) + .def("getOperators", &Sizing::getOperators, return_internal_reference<>()) + ; + + class_("Circuit", init()) + // properties + .add_property("name" , &Circuit::getName ) + .add_property("techno" , &Circuit::getTechno ) + .add_property("parameters", &Circuit::getParameters) + .add_property("netlist" , make_function(&Circuit::getNetlist , return_value_policy())) + .add_property("schematic" , make_function(&Circuit::getSchematic, return_value_policy())) + .add_property("sizing" , make_function(&Circuit::getSizing , return_value_policy())) + // accessors + .def("getValue", &Circuit::getValue) + // modifiers + .def("createNetlist" , &Circuit::createNetlist , return_value_policy()) + .def("createSchematic", &Circuit::createSchematic, return_value_policy()) + .def("createSizing" , &Circuit::createSizing , return_value_policy()) + .def("addParameter", static_cast(&Circuit::addParameter)) + .def("addParameter", static_cast(&Circuit::addParameter)) + // others + .def("readFromFile", &Circuit::readFromFile, return_value_policy()) + .staticmethod("readFromFile") + .def("writeToFile" , &Circuit::writeToFile) + ; + + // OpenChamsException translator + register_exception_translator(translator) + ; +} +} diff --git a/vlsisapd/src/openChams/src/SimulModel.cpp b/vlsisapd/src/openChams/src/SimulModel.cpp new file mode 100644 index 00000000..0f97d9bf --- /dev/null +++ b/vlsisapd/src/openChams/src/SimulModel.cpp @@ -0,0 +1,21 @@ +/* + * SimulModel.cpp + * openChams + * + * Created by damien dupuis on 06/07/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +using namespace std; + +#include "vlsisapd/openChams/SimulModel.h" + +namespace OpenChams { +SimulModel::SimulModel(unsigned id, SimulModel::Base base, SimulModel::Version version, std::string filePath) + : _id(id) + , _base(base) + , _version(version) + , _filePath(filePath) {} + +} // namespace diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h index e82483c2..b6cc4494 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h @@ -11,12 +11,14 @@ #define __OPENCHAMS_CIRCUIT_H__ #include +#include #include #include #include "vlsisapd/openChams/Name.h" #include "vlsisapd/openChams/Parameters.h" +#include "vlsisapd/openChams/SimulModel.h" namespace OpenChams { class Netlist; @@ -40,10 +42,14 @@ class Circuit { inline void addParameter(Name, double); inline void addParameter(Name, std::string); inline Parameters getParameters(); + + void addSimulModel(unsigned, SimulModel::Base, SimulModel::Version, std::string); - inline void setNetlist(Netlist*); - inline void setSchematic(Schematic*); inline void setSizing(Sizing*); + + Netlist* createNetlist(); + Schematic* createSchematic(double); + Sizing* createSizing(); bool writeToFile(std::string filePath); static Circuit* readFromFile(const std::string filePath); @@ -53,6 +59,7 @@ class Circuit { Name readParameterEq(xmlNode*, std::string&); Name readConnector(xmlNode*); void readCircuitParameters(xmlNode*); + void readSimulModels(xmlNode*); void readNetList(xmlNode*); void readInstances(xmlNode*, Netlist*); Instance* readInstance (xmlNode*, Netlist*); @@ -81,6 +88,7 @@ class Circuit { Netlist* _netlist; Schematic* _schematic; Sizing* _sizing; + map _simulModels; }; inline Name Circuit::getName() { return _name; }; @@ -92,9 +100,6 @@ inline Sizing* Circuit::getSizing() { return _sizing; }; inline void Circuit::addParameter(Name name, double value) { _params.addParameter(name, value); }; inline void Circuit::addParameter(Name name, std::string eqStr) { _params.addParameter(name, eqStr); }; inline Parameters Circuit::getParameters() { return _params; }; -inline void Circuit::setNetlist(Netlist* netlist) { _netlist = netlist; }; -inline void Circuit::setSchematic(Schematic* schem) { _schematic = schem; }; -inline void Circuit::setSizing(Sizing* sizing) { _sizing = sizing; }; } // namespace OpenChams diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Instance.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Instance.h index d907b3ae..fd961bb6 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Instance.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Instance.h @@ -27,15 +27,13 @@ class Instance { void addConnector(Name); void connect(Name connectorName, Name netName); - Instance* getInstance(Name); - inline void addParameter(Name, double); inline void addParameter(Name, std::string); - inline void addTransistor(Transistor*); inline Name getName() const; inline Name getModel(); inline Name getMosType(); inline bool isSourceBulkConnected(); + inline Netlist* getNetlist(); inline Parameters getParameters(); // pour parcourir les connecteurs inline bool hasNoConnectors(); @@ -44,6 +42,8 @@ class Instance { inline bool hasNoTransistors(); inline const std::vector& getTransistors(); + Transistor* addTransistor(Name); + private: Name _name; Name _model; @@ -57,11 +57,11 @@ class Instance { inline void Instance::addParameter(Name name, double value) { _params.addParameter(name, value); }; inline void Instance::addParameter(Name name, std::string eqStr) { _params.addParameter(name, eqStr); }; -inline void Instance::addTransistor(Transistor* tr) { _trans.push_back(tr); }; inline Name Instance::getName() const { return _name; }; inline Name Instance::getModel() { return _model; }; inline Name Instance::getMosType() { return _mosType; }; inline bool Instance::isSourceBulkConnected() { return _sourceBulkConnected; }; +inline Netlist* Instance::getNetlist() { return _netlist; }; inline Parameters Instance::getParameters() { return _params; }; inline bool Instance::hasNoConnectors() { return (_netMap.size() == 0)? true : false; }; inline const std::map& Instance::getConnectors() { return _netMap; }; diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Name.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Name.h index 3c45b55a..f220522f 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Name.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Name.h @@ -18,6 +18,7 @@ namespace OpenChams { class Name { public: + Name(); Name(std::string); Name(const char*); diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Net.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Net.h index be96a821..b565c7ab 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Net.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Net.h @@ -17,6 +17,19 @@ namespace OpenChams { class Netlist; class Net { + public: + class Connection { + public: + Connection(Name instanceName, Name connectorName); + + inline Name getInstanceName() const; + inline Name getConnectorName() const; + + private: + Name _instanceName; + Name _connectorName; + }; + public: Net(Name netName, Name typeName, bool, Netlist*); @@ -26,27 +39,30 @@ class Net { inline Name getType(); inline bool isExternal(); inline Netlist* getNetlist(); - inline bool hasNoConnectors(); + inline bool hasNoConnections(); //inline vector >::iterator getFirstConnectionIt(); //inline vector >::iterator getLastConnectionIt(); - inline const std::vector >& getConnections(); + inline const std::vector& getConnections(); private: Name _name; Name _typeName; bool _isExternal; Netlist* _netlist; - std::vector > _connections; // + std::vector _connections; // }; inline Name Net::getName() const { return _name; }; 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 bool Net::hasNoConnections() { return (_connections.size() == 0)? true : false; }; //inline vector >::iterator Net::getFirstConnectionIt() { return _connections.begin();}; //inline vector >::iterator Net::getLastConnectionIt() { return _connections.end();}; -inline const std::vector >& Net::getConnections() { return _connections; }; +inline const std::vector& Net::getConnections() { return _connections; }; + +inline Name Net::Connection::getInstanceName() const { return _instanceName; }; +inline Name Net::Connection::getConnectorName() const { return _connectorName; }; } // namespace #endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Netlist.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Netlist.h index e9b868de..d75e9833 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Netlist.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Netlist.h @@ -22,8 +22,8 @@ class Netlist { public: Netlist(Circuit*); - void addInstance(Instance*); - void addNet(Net*); + Instance* addInstance(Name name, Name model, Name mosType, bool); + Net* addNet (Name name, Name type , bool); Instance* getInstance(Name); Net* getNet(Name); diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Operator.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Operator.h index f57bca1b..639e8136 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Operator.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Operator.h @@ -34,8 +34,10 @@ class Operator { public: Operator(Name operatorName, Name simulModel, unsigned callOrder); - void addConstraint(Name paramName, Name ref, Name refParam, double factor = 1.0); - void addConstraint(Name paramName, Name refEquation, double factor = 1.0); + void addConstraint(Name paramName, Name ref, Name refParam ); + void addConstraint(Name paramName, Name ref, Name refParam, double factor); + void addConstraint(Name paramName, Name refEquation ); + void addConstraint(Name paramName, Name refEquation, double factor); inline Name getName(); inline Name getSimulModel(); diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/PySTLMapWrapper.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/PySTLMapWrapper.h new file mode 100644 index 00000000..1007b72b --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/PySTLMapWrapper.h @@ -0,0 +1,87 @@ +#include + +#include + +namespace OpenChams { +// since we want to wrap std::map with cimple pointers (no boost::shared_ptr), +// we cannot use map_indexing_suite which has not the right return_value_policy. +// std::maps with no points value are wrapped using map_indexing_suite technique. +// +// This templated map_item struct is intended to be used for 'manual' wrapping: +template +struct map_item { + typedef std::map Map; + + static Val get(Map & self, const Key idx) { + if (self.find(idx) == self.end()) { + PyErr_SetString(PyExc_KeyError,"Map key not found"); + throw_error_already_set(); + } + return self[idx]; + } + + static void set(Map& self, const Key idx, const Val val) { self[idx]=val; } + static void del(Map& self, const Key n) { self.erase(n); } + static bool in (Map const& self, const Key n) { return self.find(n) != self.end(); } + + static list keys(Map const& self) { + list t; + for(typename Map::const_iterator it = self.begin() ; it!=self.end() ; ++it) + t.append(it->first); + return t; + } + + static list values(Map const& self) { + list t; + for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it) + t.append(it->second); + return t; + } + + static list items(Map const& self) { + list t; + for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it) + t.append( make_tuple(it->first, it->second) ); + return t; + } +}; + +#define STL_MAP_WRAPPING_PTR(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME) \ + class_ >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \ + .def_readonly ("key" , &std::pair::first ) \ + .def_readwrite("value", &std::pair::second) \ + ; \ + class_ >(PYTHON_TYPE_NAME) \ + .def("__len__" , &std::map::size) \ + .def("__iter__" , boost::python::iterator, return_internal_reference<> >()) \ + .def("__getitem__" , &map_item().get, return_internal_reference<>()) \ + .def("__setitem__" , &map_item().set ) \ + .def("__delitem__" , &map_item().del ) \ + .def("__contains__", &map_item().in ) \ + .def("clear" , &std::map::clear ) \ + .def("has_key" , &map_item().in ) \ + .def("keys" , &map_item().keys ) \ + .def("values" , &map_item().values) \ + .def("items" , &map_item().items ) \ + ; + +#define STL_MAP_WRAPPING(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME) \ + class_ >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \ + .def_readonly ("key" , &std::pair::first ) \ + .def_readwrite("value", &std::pair::second) \ + ; \ + class_ >(PYTHON_TYPE_NAME) \ + .def("__len__" , &std::map::size) \ + .def("__iter__" , boost::python::iterator, return_internal_reference<> >()) \ + .def("__getitem__" , &map_item().get ) \ + .def("__setitem__" , &map_item().set ) \ + .def("__delitem__" , &map_item().del ) \ + .def("__contains__", &map_item().in ) \ + .def("clear" , &std::map::clear ) \ + .def("has_key" , &map_item().in ) \ + .def("keys" , &map_item().keys ) \ + .def("values" , &map_item().values) \ + .def("items" , &map_item().items ) \ + ; + +} // namespace diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h index 8f56758c..34e7f917 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h @@ -25,7 +25,7 @@ class Schematic { inline double getX(); inline double getY(); - inline Name getSymetry(); + inline Name getSymmetry(); private: double _x; @@ -51,9 +51,9 @@ 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; }; +inline double Schematic::Infos::getX() { return _x; }; +inline double Schematic::Infos::getY() { return _y; }; +inline Name Schematic::Infos::getSymmetry() { return _sym; }; } // namespace #endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/SimulModel.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/SimulModel.h new file mode 100644 index 00000000..0e1cb104 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/SimulModel.h @@ -0,0 +1,49 @@ +/* + * SimulModel.h + * openChams + * + * Created by damien dupuis on 06/07/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_SIMULMODEL_H__ +#define __OPENCHAMS_SIMULMODEL_H__ + +#include "vlsisapd/openChams/Name.h" + +namespace OpenChams { +class SimulModel { + public: + enum Base { BSIM3V3=0, + BSIM4=1, + PSP=2 + }; + enum Version { UNDEFINED=0, + SVT=1, + HVT=2, + LVT=3 + }; + + SimulModel(unsigned, Base, Version, std::string); + + inline unsigned getId() const; + inline Base getBase(); + inline Version getVersion(); + inline std::string getFilePath(); + + private: + unsigned _id; + Base _base; + Version _version; + std::string _filePath; +}; + +inline unsigned SimulModel::getId() const { return _id; }; +inline SimulModel::Base SimulModel::getBase() { return _base; }; +inline SimulModel::Version SimulModel::getVersion() { return _version; }; +inline std::string SimulModel::getFilePath() { return _filePath;}; + +} // namespace +#endif +