diff --git a/vlsisapd/src/openChams/src/CMakeLists.txt b/vlsisapd/src/openChams/src/CMakeLists.txt index a308f8f3..6e86a39a 100644 --- a/vlsisapd/src/openChams/src/CMakeLists.txt +++ b/vlsisapd/src/openChams/src/CMakeLists.txt @@ -17,6 +17,11 @@ SET ( hpps vlsisapd/openChams/Circuit.h vlsisapd/openChams/Port.h vlsisapd/openChams/Wire.h vlsisapd/openChams/OpenChamsException.h + vlsisapd/openChams/Equation.h + vlsisapd/openChams/HighLevelCstr.h + vlsisapd/openChams/NRCCstr.h + vlsisapd/openChams/DDP.h + vlsisapd/openChams/DesignerCstrOC.h ) SET ( cpps Circuit.cpp Netlist.cpp @@ -33,6 +38,11 @@ SET ( cpps Circuit.cpp Node.cpp Transistor.cpp Wire.cpp + Equation.cpp + HighLevelCstr.cpp + NRCCstr.cpp + DDP.cpp + DesignerCstrOC.cpp ) SET ( pycpps PyOpenChams.cpp ) diff --git a/vlsisapd/src/openChams/src/Circuit.cpp b/vlsisapd/src/openChams/src/Circuit.cpp index 8751e08a..36aa3e5f 100644 --- a/vlsisapd/src/openChams/src/Circuit.cpp +++ b/vlsisapd/src/openChams/src/Circuit.cpp @@ -29,37 +29,42 @@ using namespace std; #include "vlsisapd/openChams/Port.h" #include "vlsisapd/openChams/Wire.h" #include "vlsisapd/openChams/OpenChamsException.h" +#include "vlsisapd/openChams/Equation.h" +#include "vlsisapd/openChams/HighLevelCstr.h" +#include "vlsisapd/openChams/NRCCstr.h" +#include "vlsisapd/openChams/DDP.h" +#include "vlsisapd/openChams/DesignerCstrOC.h" namespace { - template T getValue(xmlChar* str) { - std::istringstream iss; - iss.str((const char*) str); - T res; - iss >> res; - return res; - } + template T getValue(xmlChar* str) { + std::istringstream iss; + iss.str((const char*) str); + T res; + iss >> res; + return res; + } } namespace OpenChams { -static bool readSubCircuitsPathsDone = false; -static bool readCircuitParametersDone = 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; -static bool readLayoutDone = false; + static bool readSubCircuitsPathsDone = false; + static bool readCircuitParametersDone = 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; + static bool readLayoutDone = false; -Circuit::Circuit(Name name, Name techno) : _name(name) - , _absolutePath("") - , _techno(techno) - , _netlist(NULL) - , _schematic(NULL) - , _sizing(NULL) - , _layout(NULL) -{ + Circuit::Circuit(Name name, Name techno) : _name(name) + , _absolutePath("") + , _techno(techno) + , _netlist(NULL) + , _schematic(NULL) + , _sizing(NULL) + , _layout(NULL) + { readSubCircuitsPathsDone = false; readCircuitParametersDone = false; readSimulModelsDone = false; @@ -69,255 +74,255 @@ Circuit::Circuit(Name name, Name techno) : _name(name) readSchematicDone = false; readSizingDone = false; readLayoutDone = false; -} + } -// COMPARISON FUNCTION // -bool ConnectionsSort(const Net::Connection* c1, const Net::Connection* c2) { + // COMPARISON FUNCTION // + bool ConnectionsSort(const Net::Connection* c1, const Net::Connection* c2) { return c1->getInstanceName() < c2->getInstanceName(); -} + } -bool InstanceNameSort(const Instance* i1, const Instance* i2) { + bool InstanceNameSort(const Instance* i1, const Instance* i2) { return i1->getName() < i2->getName(); -} + } -bool NetNameSort(const Net* n1, const Net* n2) { + bool NetNameSort(const Net* n1, const Net* n2) { return n1->getName() < n2->getName(); -} + } -// USEFUL // -void Circuit::check_uppercase(string& str, vector& compares, string message) { + // USEFUL // + 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 (str == compares[i]) { + equal = true; + } } if (!equal) { - throw OpenChamsException(message); + throw OpenChamsException(message); } -} + } -void Circuit::check_lowercase(string& str, vector& compares, string 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 (str == compares[i]) { + equal = true; + } } if (!equal) { - throw OpenChamsException(message); + throw OpenChamsException(message); } -} + } -void Circuit::addSimulModel(unsigned id, SimulModel::Base base, SimulModel::Version version, std::string filePath) { + 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."); + throw OpenChamsException("[ERROR] Cannot define two SimulModels' models with the same ID."); _simulModels[id] = sim; -} + } -Name Circuit::readParameter(xmlNode* node, double& value) { + Name Circuit::readParameter(xmlNode* node, double& value) { xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* valueC = xmlGetProp(node, (xmlChar*)"value"); if (paramNameC && valueC) { - Name name((const char*)paramNameC); - value = ::getValue(valueC); - return name; + Name name((const char*)paramNameC); + value = ::getValue(valueC); + return name; } else { - throw OpenChamsException("[ERROR] 'parameter' node must have 'name' and 'value' properties."); + throw OpenChamsException("[ERROR] 'parameter' node must have 'name' and 'value' properties."); } -} + } -Name Circuit::readParameterEq(xmlNode* node, string& eqStr) { + Name Circuit::readParameterEq(xmlNode* node, string& eqStr) { xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* equationC = xmlGetProp(node, (xmlChar*)"equation"); if (paramNameC && equationC) { - Name name((const char*)paramNameC); - eqStr = string ((const char*)equationC); - return name; + Name name((const char*)paramNameC); + eqStr = string ((const char*)equationC); + return name; } else { - throw OpenChamsException("[ERROR] 'parameterEq' node must have 'name' and 'equation' properties."); + throw OpenChamsException("[ERROR] 'parameterEq' node must have 'name' and 'equation' properties."); } -} + } -Name Circuit::readConnector(xmlNode* node) { + Name Circuit::readConnector(xmlNode* node) { xmlChar* connectorNameC = xmlGetProp(node, (xmlChar*)"name"); if (connectorNameC) { - Name name((const char*)connectorNameC); - return name; + Name name((const char*)connectorNameC); + return name; } else { - throw OpenChamsException("[ERROR] 'connector' node must have 'name' property."); - //return Name(""); + throw OpenChamsException("[ERROR] 'connector' node must have 'name' property."); + //return Name(""); } -} + } -// CIRCUIT // -void Circuit::readSubCircuitsPaths(xmlNode* node) { + // CIRCUIT // + void Circuit::readSubCircuitsPaths(xmlNode* node) { if (readSubCircuitsPathsDone) { - cerr << "[WARNING] Only one 'subCircuitsPaths' node is allowed in circuit, others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'subCircuitsPaths' node is allowed in circuit, others will be ignored." << endl; + return; } if (node->type == XML_ELEMENT_NODE && node->children) { - for (xmlNode* pathNode = node->children ; pathNode ; pathNode = pathNode->next) { - if (pathNode->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(pathNode->name, (xmlChar*)"path")) { - xmlChar* pathC = xmlGetProp(pathNode, (xmlChar*)"path"); - if (pathC) { - string path((const char*)pathC); - if (path[0] != '/') { // this is not an absolute path - path = _absolutePath+"/"+path; - } - _subCircuitsPaths.push_back(path); - } else { - throw OpenChamsException("[ERROR] 'path' node must have 'path' property."); - } - } else { - cerr << "[WARNING] Only 'path' nodes are allowed under 'subCircuitsPaths' node." << endl; - return; - } - } - } + for (xmlNode* pathNode = node->children ; pathNode ; pathNode = pathNode->next) { + if (pathNode->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(pathNode->name, (xmlChar*)"path")) { + xmlChar* pathC = xmlGetProp(pathNode, (xmlChar*)"path"); + if (pathC) { + string path((const char*)pathC); + if (path[0] != '/') { // this is not an absolute path + path = _absolutePath+"/"+path; + } + _subCircuitsPaths.push_back(path); + } else { + throw OpenChamsException("[ERROR] 'path' node must have 'path' property."); + } + } else { + cerr << "[WARNING] Only 'path' nodes are allowed under 'subCircuitsPaths' node." << endl; + return; + } + } + } } readSubCircuitsPathsDone = true; -} + } -void Circuit::readCircuitParameters(xmlNode* node) { + void Circuit::readCircuitParameters(xmlNode* node) { if (readCircuitParametersDone) { - cerr << "[WARNING] Only one 'parameters' node is allowed in circuit, others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'parameters' node is allowed in circuit, others will be ignored." << endl; + return; } if (node->type == XML_ELEMENT_NODE && node->children) { - for (xmlNode* paramNode = node->children ; paramNode ; paramNode = paramNode->next) { - if (paramNode->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(paramNode->name, (xmlChar*)"parameter")) { - double value = 0.0; - Name paramName = readParameter(paramNode, value); - if (paramName == Name("")) return; // error - addParameter(paramName, value); - } else if (xmlStrEqual(paramNode->name, (xmlChar*)"parameterEq")) { - string eqStr = ""; - Name paramName = readParameterEq(paramNode, eqStr); - if (paramName == Name("")) return; // error - addParameter(paramName, eqStr); - } else { - cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'parameters' node." << endl; - return; - } - } - } - } + for (xmlNode* paramNode = node->children ; paramNode ; paramNode = paramNode->next) { + if (paramNode->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(paramNode->name, (xmlChar*)"parameter")) { + double value = 0.0; + Name paramName = readParameter(paramNode, value); + if (paramName == Name("")) return; // error + addParameter(paramName, value); + } else if (xmlStrEqual(paramNode->name, (xmlChar*)"parameterEq")) { + string eqStr = ""; + Name paramName = readParameterEq(paramNode, eqStr); + if (paramName == Name("")) return; // error + addParameter(paramName, eqStr); + } else { + cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'parameters' node." << endl; + return; + } + } + } + } readCircuitParametersDone = true; -} + } -void Circuit::readSimulModels(xmlNode* node) { + void Circuit::readSimulModels(xmlNode* node) { if (readSimulModelsDone) { - cerr << "[WARNING] Only one 'simulModels' node is allowed in circuit, others will be ignored." << endl; - return; + 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; - } - } - } + 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) { + // NETLIST // + void Circuit::readNetList(xmlNode* node) { if (readNetListDone) { - cerr << "[WARNING] Only one 'netlist' node is allowed in circuit, others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'netlist' node is allowed in circuit, others will be ignored." << endl; + return; } Netlist* netlist = new Netlist(this); xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"instances")) { - readInstances(node, netlist); - } else if (xmlStrEqual(node->name, (xmlChar*)"nets")) { - readNets(node, netlist); - } else { - cerr << "[WARNING] Only 'instances' and 'nets' nodes are allowed in 'netlist', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instances")) { + readInstances(node, netlist); + } else if (xmlStrEqual(node->name, (xmlChar*)"nets")) { + readNets(node, netlist); + } else { + cerr << "[WARNING] Only 'instances' and 'nets' nodes are allowed in 'netlist', others will be ignored." << endl; + } + } } readNetListDone = true; _netlist = netlist; -} + } -// INSTANCES // -void Circuit::readInstances(xmlNode* node, Netlist* netlist) { + // INSTANCES // + void Circuit::readInstances(xmlNode* node, Netlist* netlist) { if (readInstancesDone) { - cerr << "[WARNING] Only one 'instances' node is allowed in 'netlist', others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'instances' node is allowed in 'netlist', others will be ignored." << endl; + return; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"instance")) { - readInstance(node, netlist); - } else { - cerr << "[WARNING] Only 'instance' nodes are allowed in 'instances', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstance(node, netlist); + } else { + cerr << "[WARNING] Only 'instance' nodes are allowed in 'instances', others will be ignored." << endl; + } + } } readInstancesDone = true; -} + } -Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) { + Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) { xmlChar* iNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* iModelC = xmlGetProp(node, (xmlChar*)"model"); xmlChar* iOrderC = xmlGetProp(node, (xmlChar*)"order"); @@ -325,415 +330,415 @@ Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) { xmlChar* iSBCC = xmlGetProp(node, (xmlChar*)"sourceBulkConnected"); Instance* inst = NULL; if (iNameC && iModelC && iOrderC && iMOSC && iSBCC) { // this is a device - Name instanceName((const char*)iNameC); - Name modelName((const char*)iModelC); - unsigned order = ::getValue(iOrderC); - string mosStr((const char*)iMOSC); - string mosComp[2] = {"NMOS", "PMOS"}; - vector mosComps (mosComp, mosComp+2); - check_uppercase(mosStr, mosComps, "[ERROR] In 'instance', 'mostype' property 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' property must be 'true', 'false', 'on' or 'off'."); - bool sourceBulkConnected = ((sourceBulkStr == "true") || (sourceBulkStr == "on")) ? true : false; - inst = (Instance*)netlist->addDevice(instanceName, modelName, order, Name(mosStr), sourceBulkConnected); + Name instanceName((const char*)iNameC); + Name modelName((const char*)iModelC); + unsigned order = ::getValue(iOrderC); + string mosStr((const char*)iMOSC); + string mosComp[2] = {"NMOS", "PMOS"}; + vector mosComps (mosComp, mosComp+2); + check_uppercase(mosStr, mosComps, "[ERROR] In 'instance', 'mostype' property 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' property must be 'true', 'false', 'on' or 'off'."); + bool sourceBulkConnected = ((sourceBulkStr == "true") || (sourceBulkStr == "on")) ? true : false; + inst = (Instance*)netlist->addDevice(instanceName, modelName, order, Name(mosStr), sourceBulkConnected); } else if (iNameC && iModelC && iOrderC && !iMOSC && !iSBCC) { // this is a subcircuit - Name instanceName((const char*)iNameC); - Name modelName((const char*)iModelC); - unsigned order = ::getValue(iOrderC); - inst = netlist->addInstance(instanceName, modelName, order); + Name instanceName((const char*)iNameC); + Name modelName((const char*)iModelC); + unsigned order = ::getValue(iOrderC); + inst = netlist->addInstance(instanceName, modelName, order); } else { - throw OpenChamsException("[ERROR] 'instance' node must have ('name', 'model' and 'order') or ('name', 'model', 'order', 'mostype' and 'sourceBulkConnected') properties."); - //return inst; + throw OpenChamsException("[ERROR] 'instance' node must have ('name', 'model' and 'order') or ('name', 'model', 'order', 'mostype' and 'sourceBulkConnected') properties."); + //return inst; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"connectors")) { - readInstanceConnectors(node, inst); - } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { - readInstanceParameters(node, inst); - } else if (xmlStrEqual(node->name, (xmlChar*)"transistors")) { - if (!dynamic_cast(inst)) - throw OpenChamsException("[ERROR] Only device 'instance' (with 'mostype' and 'sourceBulkConnected' properties) can have 'transistors' section."); - readInstanceTransistors(node, static_cast(inst)); - } else { - //cerr << "[WARNING] Only 'parameters' node is allowed in 'instance', others will be ignored." << endl; - cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"connectors")) { + readInstanceConnectors(node, inst); + } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { + readInstanceParameters(node, inst); + } else if (xmlStrEqual(node->name, (xmlChar*)"transistors")) { + if (!dynamic_cast(inst)) + throw OpenChamsException("[ERROR] Only device 'instance' (with 'mostype' and 'sourceBulkConnected' properties) can have 'transistors' section."); + readInstanceTransistors(node, static_cast(inst)); + } else { + //cerr << "[WARNING] Only 'parameters' node is allowed in 'instance', others will be ignored." << endl; + cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; + } + } } return inst; -} + } -void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) { - xmlNode* child = node->children; - for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"connector")) { - Name connectorName = readConnector(node); - if (connectorName == Name("")) return; // error - inst->addConnector(connectorName); - } - } - } -} - -void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) { + void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"parameter")) { - double value = 0.0; - Name paramName = readParameter(node, value); - if (paramName == Name("")) return; // error - inst->addParameter(paramName, value); - } else if (xmlStrEqual(node->name, (xmlChar*)"parameterEq")) { - string eqStr = ""; - Name paramName = readParameterEq(node, eqStr); - if (paramName == Name("")) return; // error - inst->addParameter(paramName, eqStr); - } else { - cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'instance' node." << endl; - return; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"connector")) { + Name connectorName = readConnector(node); + if (connectorName == Name("")) return; // error + inst->addConnector(connectorName); + } + } } -} - -void Circuit::readInstanceTransistors(xmlNode* node, Device* dev) { + } + + void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"transistor")) { - readTransistor(node, dev); - } else { - cerr << "[WARNING] Only 'transistor' nodes are allowed in 'transistors', others will be ignored." << endl; - } - - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"parameter")) { + double value = 0.0; + Name paramName = readParameter(node, value); + if (paramName == Name("")) return; // error + inst->addParameter(paramName, value); + } else if (xmlStrEqual(node->name, (xmlChar*)"parameterEq")) { + string eqStr = ""; + Name paramName = readParameterEq(node, eqStr); + if (paramName == Name("")) return; // error + inst->addParameter(paramName, eqStr); + } else { + cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'instance' node." << endl; + return; + } + } } -} + } + + void Circuit::readInstanceTransistors(xmlNode* node, Device* dev) { + xmlNode* child = node->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"transistor")) { + readTransistor(node, dev); + } else { + cerr << "[WARNING] Only 'transistor' nodes are allowed in 'transistors', others will be ignored." << endl; + } + + } + } + } -void Circuit::readTransistor(xmlNode* node, Device* dev) { + void Circuit::readTransistor(xmlNode* node, Device* dev) { xmlChar* tNameC = xmlGetProp(node, (xmlChar*)"name"); Transistor* trans = NULL; if (tNameC) { - Name tName((const char*)tNameC); - trans = dev->addTransistor(tName); + Name tName((const char*)tNameC); + trans = dev->addTransistor(tName); } else { - throw OpenChamsException("[ERROR] 'transistor' node must have 'name' property."); - //return inst; + throw OpenChamsException("[ERROR] 'transistor' node must have 'name' property."); + //return inst; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"connection")) { - readTransistorConnection(node, trans); - } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { - cerr << "Transistor parameters NOT SUPPORTED YET" << endl; - } else { - cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"connection")) { + readTransistorConnection(node, trans); + } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { + cerr << "Transistor parameters NOT SUPPORTED YET" << endl; + } else { + cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; + } + } } -} + } -void Circuit::readTransistorConnection(xmlNode* node, Transistor* trans) { + void Circuit::readTransistorConnection(xmlNode* node, Transistor* trans) { xmlChar* gateC = xmlGetProp(node, (xmlChar*)"gate"); xmlChar* sourceC = xmlGetProp(node, (xmlChar*)"source"); xmlChar* drainC = xmlGetProp(node, (xmlChar*)"drain"); xmlChar* bulkC = xmlGetProp(node, (xmlChar*)"bulk"); if (gateC && sourceC && drainC && bulkC) { - Name gateN ((const char*)gateC); - Name sourceN((const char*)sourceC); - Name drainN ((const char*)drainC); - Name bulkN ((const char*)bulkC); - trans->setGate(gateN); - trans->setSource(sourceN); - trans->setDrain(drainN); - trans->setBulk(bulkN); + Name gateN ((const char*)gateC); + Name sourceN((const char*)sourceC); + Name drainN ((const char*)drainC); + Name bulkN ((const char*)bulkC); + trans->setGate(gateN); + trans->setSource(sourceN); + trans->setDrain(drainN); + trans->setBulk(bulkN); } else { - throw OpenChamsException("[ERROR] 'connection' node must have 'gate', 'source', 'drain' and 'bulk' properties."); + throw OpenChamsException("[ERROR] 'connection' node must have 'gate', 'source', 'drain' and 'bulk' properties."); } -} + } -// NETS // -void Circuit::readNets(xmlNode* node, Netlist* netlist) { + // NETS // + void Circuit::readNets(xmlNode* node, Netlist* netlist) { if (readNetsDone) { - cerr << "[WARNING] Only one 'nets' node is allowed in 'netlist', others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'nets' node is allowed in 'netlist', others will be ignored." << endl; + return; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"net")) { - readNet(node, netlist); - } else { - cerr << "[WARNING] Only 'net' nodes are allowed in 'nets', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"net")) { + readNet(node, netlist); + } else { + cerr << "[WARNING] Only 'net' nodes are allowed in 'nets', others will be ignored." << endl; + } + } } readNetsDone = true; -} + } -Net* Circuit::readNet(xmlNode* node, Netlist* netlist) { + Net* Circuit::readNet(xmlNode* node, Netlist* netlist) { xmlChar* nNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* nTypeC = xmlGetProp(node, (xmlChar*)"type"); xmlChar* nExternC = xmlGetProp(node, (xmlChar*)"isExternal"); Net* net = NULL; if (nNameC && nTypeC && nExternC) { - Name netName((const char*)nNameC); - 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); - 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 = netlist->addNet(netName, Name(typeStr), isExternal); + Name netName((const char*)nNameC); + 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); + 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 = netlist->addNet(netName, Name(typeStr), isExternal); } else { - throw OpenChamsException("[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties."); - //return net; + throw OpenChamsException("[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties."); + //return net; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"connector")) { - readNetConnector(node, net); - } else { - cerr << "[WARNING] Only 'connector' nodes are allowed in 'net', others will be ignored." << endl; - return NULL; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"connector")) { + readNetConnector(node, net); + } else { + cerr << "[WARNING] Only 'connector' nodes are allowed in 'net', others will be ignored." << endl; + return NULL; + } + } } return net; -} + } -void Circuit::readNetConnector(xmlNode* node, Net* net) { + void Circuit::readNetConnector(xmlNode* node, Net* net) { xmlChar* instanceNameC = xmlGetProp(node, (xmlChar*)"instance"); xmlChar* connectorNameC = xmlGetProp(node, (xmlChar*)"name"); if (instanceNameC && connectorNameC) { - Name iName((const char*)instanceNameC); - Name cName((const char*)connectorNameC); - Instance* inst = net->getNetlist()->getInstance(iName); - if (!inst) { - 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); + Name iName((const char*)instanceNameC); + Name cName((const char*)connectorNameC); + Instance* inst = net->getNetlist()->getInstance(iName); + if (!inst) { + 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 { - throw OpenChamsException("[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)."); + throw OpenChamsException("[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)."); } -} + } -// SCHEMATIC // -void Circuit::readSchematic(xmlNode* node) { + // SCHEMATIC // + void Circuit::readSchematic(xmlNode* node) { if (readSchematicDone) { - cerr << "[WARNING] Only one 'schematic' node is allowed in circuit, others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'schematic' node is allowed in circuit, others will be ignored." << endl; + return; } Schematic* schematic = new Schematic(this); 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 if (xmlStrEqual(node->name, (xmlChar*)"net")) { - readNetSchematic(node, this); - } else { - cerr << "[WARNING] Only 'instance' and 'nets' nodes are allowed in 'schematic', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstanceSchematic(node, schematic); + } else if (xmlStrEqual(node->name, (xmlChar*)"net")) { + readNetSchematic(node, this); + } else { + cerr << "[WARNING] Only 'instance' and 'nets' nodes are allowed in 'schematic', others will be ignored." << endl; + } + } } readSchematicDone = true; _schematic = schematic; -} + } -void Circuit::readInstanceSchematic(xmlNode* node, 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* orientC = xmlGetProp(node, (xmlChar*)"orient"); if (nameC && xC && yC && orientC) { - Name iName((const char*)nameC); - double x = ::getValue(xC); - double y = ::getValue(yC); - string orientStr((const char*)orientC); - string orientComp[8] = {"ID", "R1", "R2", "R3", "MX", "XR", "MY", "YR"}; - vector orientComps (orientComp, orientComp+8); - check_uppercase(orientStr, orientComps, "[ERROR] In 'schematic'.'instance', 'orient' must be 'ID', 'R1', 'R2', 'R3', 'MX', 'XR', 'MY' or 'YR'."); - schematic->addInstance(iName, x, y, Name(orientStr)); + Name iName((const char*)nameC); + double x = ::getValue(xC); + double y = ::getValue(yC); + string orientStr((const char*)orientC); + string orientComp[8] = {"ID", "R1", "R2", "R3", "MX", "XR", "MY", "YR"}; + vector orientComps (orientComp, orientComp+8); + check_uppercase(orientStr, orientComps, "[ERROR] In 'schematic'.'instance', 'orient' must be 'ID', 'R1', 'R2', 'R3', 'MX', 'XR', 'MY' or 'YR'."); + schematic->addInstance(iName, x, y, Name(orientStr)); } else { - throw OpenChamsException("[ERROR] 'instance' node in 'schematic' must have 'name', 'x', 'y' and 'orient' properties."); + throw OpenChamsException("[ERROR] 'instance' node in 'schematic' must have 'name', 'x', 'y' and 'orient' properties."); } -} + } -void Circuit::readNetSchematic(xmlNode* node, Circuit* circuit) { + void Circuit::readNetSchematic(xmlNode* node, Circuit* circuit) { xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); if (nameC) { - Name nName((const char*)nameC); - Net* net = circuit->getNetlist()->getNet(nName); - if (!net) { - string error ("[ERROR] In 'schematic' section cannot specify wires for net "); - error += nName.getString(); - error += " since it has not been defined in netlist section."; - throw OpenChamsException(error); - } - xmlNode* child = node->children; - for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"port")) { - readPortSchematic(node, net); - } else if (xmlStrEqual(node->name, (xmlChar*)"wire")) { - readWireSchematic(node, net); - } else { - cerr << "[WARNING] Only 'port' and 'wire' nodes are allowed in 'schematic'.'net', others will be ignored." << endl; - } - } - } + Name nName((const char*)nameC); + Net* net = circuit->getNetlist()->getNet(nName); + if (!net) { + string error ("[ERROR] In 'schematic' section cannot specify wires for net "); + error += nName.getString(); + error += " since it has not been defined in netlist section."; + throw OpenChamsException(error); + } + xmlNode* child = node->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"port")) { + readPortSchematic(node, net); + } else if (xmlStrEqual(node->name, (xmlChar*)"wire")) { + readWireSchematic(node, net); + } else { + cerr << "[WARNING] Only 'port' and 'wire' nodes are allowed in 'schematic'.'net', others will be ignored." << endl; + } + } + } } else { - throw OpenChamsException("[ERROR] 'net' node in schematic must have 'name' property."); + throw OpenChamsException("[ERROR] 'net' node in schematic must have 'name' property."); } -} + } -void Circuit::readPortSchematic(xmlNode* node, Net* net) { + void Circuit::readPortSchematic(xmlNode* node, Net* net) { xmlChar* typeC = xmlGetProp(node, (xmlChar*)"type"); xmlChar* idxC = xmlGetProp(node, (xmlChar*)"idx"); xmlChar* xC = xmlGetProp(node, (xmlChar*)"x"); xmlChar* yC = xmlGetProp(node, (xmlChar*)"y"); xmlChar* orientC = xmlGetProp(node, (xmlChar*)"orient"); if (typeC && idxC && xC && yC && orientC) { - Name pType((const char*)typeC); - unsigned idx = ::getValue(idxC); - double x = ::getValue(xC); - double y = ::getValue(yC); - string orientStr((const char*)orientC); - string orientComp[8] = {"ID", "R1", "R2", "R3", "MX", "XR", "MY", "YR"}; - vector orientComps (orientComp, orientComp+8); - check_uppercase(orientStr, orientComps, "[ERROR] In 'schematic'.'port', 'orient' must be 'ID', 'R1', 'R2', 'R3', 'MX', 'XR', 'MY' or 'YR'."); - net->addPort(pType, idx, x, y, Name(orientStr)); + Name pType((const char*)typeC); + unsigned idx = ::getValue(idxC); + double x = ::getValue(xC); + double y = ::getValue(yC); + string orientStr((const char*)orientC); + string orientComp[8] = {"ID", "R1", "R2", "R3", "MX", "XR", "MY", "YR"}; + vector orientComps (orientComp, orientComp+8); + check_uppercase(orientStr, orientComps, "[ERROR] In 'schematic'.'port', 'orient' must be 'ID', 'R1', 'R2', 'R3', 'MX', 'XR', 'MY' or 'YR'."); + net->addPort(pType, idx, x, y, Name(orientStr)); } else { - throw OpenChamsException("[ERROR] 'schematic'.'port' must have 'type', 'idx', 'x', 'y' and 'orient' properties."); + throw OpenChamsException("[ERROR] 'schematic'.'port' must have 'type', 'idx', 'x', 'y' and 'orient' properties."); } -} + } -void Circuit::readWireSchematic(xmlNode* node, Net* net) { + void Circuit::readWireSchematic(xmlNode* node, Net* net) { Wire* wire = net->addWire(); xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"connector")) { - xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); - xmlChar* plugC = xmlGetProp(node, (xmlChar*)"plug"); - xmlChar* idxC = xmlGetProp(node, (xmlChar*)"idx"); - if (nameC && plugC) { - Name name((const char*)nameC); - Name plug((const char*)plugC); - if (!wire->getStartPoint()) { - wire->setStartPoint(name, plug); - } else if (!wire->getEndPoint()) { - wire->setEndPoint(name, plug); - } else { - throw OpenChamsException("[ERROR] In 'schematic' a 'wire' must have exactly 2 connectors (not more)."); - } - } else if (idxC) { - unsigned idx = ::getValue(idxC); - if (!wire->getStartPoint()) { - wire->setStartPoint(idx); - } else if (!wire->getEndPoint()) { - wire->setEndPoint(idx); - } else { - throw OpenChamsException("[ERROR] In 'schematic' a 'wire' must have exactly 2 connectors (not more)."); - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"connector")) { + xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); + xmlChar* plugC = xmlGetProp(node, (xmlChar*)"plug"); + xmlChar* idxC = xmlGetProp(node, (xmlChar*)"idx"); + if (nameC && plugC) { + Name name((const char*)nameC); + Name plug((const char*)plugC); + if (!wire->getStartPoint()) { + wire->setStartPoint(name, plug); + } else if (!wire->getEndPoint()) { + wire->setEndPoint(name, plug); + } else { + throw OpenChamsException("[ERROR] In 'schematic' a 'wire' must have exactly 2 connectors (not more)."); + } + } else if (idxC) { + unsigned idx = ::getValue(idxC); + if (!wire->getStartPoint()) { + wire->setStartPoint(idx); + } else if (!wire->getEndPoint()) { + wire->setEndPoint(idx); + } else { + throw OpenChamsException("[ERROR] In 'schematic' a 'wire' must have exactly 2 connectors (not more)."); + } - } else { - throw OpenChamsException("[ERROR] 'schematic'.'net'.'connector' node must have 'name' & 'plug' OR 'idx' properties. "); - } - } else if (xmlStrEqual(node->name, (xmlChar*)"point")) { - xmlChar* xC = xmlGetProp(node, (xmlChar*)"x"); - xmlChar* yC = xmlGetProp(node, (xmlChar*)"y"); - if (xC && yC) { - double x = ::getValue(xC); - double y = ::getValue(yC); - wire->addIntermediatePoint(x, y); // check is done inside the method (start/end points) - } else { - throw OpenChamsException("[ERROR] 'schematic'.'net'.'point' node must have 'x' and 'y' properties."); - } - } else { - cerr << "[WARNING] Only 'connector' and 'points' nodes are allowed in 'schematic'.'net'.'wire', others will be ignored." << endl; - } - } + } else { + throw OpenChamsException("[ERROR] 'schematic'.'net'.'connector' node must have 'name' & 'plug' OR 'idx' properties. "); + } + } else if (xmlStrEqual(node->name, (xmlChar*)"point")) { + xmlChar* xC = xmlGetProp(node, (xmlChar*)"x"); + xmlChar* yC = xmlGetProp(node, (xmlChar*)"y"); + if (xC && yC) { + double x = ::getValue(xC); + double y = ::getValue(yC); + wire->addIntermediatePoint(x, y); // check is done inside the method (start/end points) + } else { + throw OpenChamsException("[ERROR] 'schematic'.'net'.'point' node must have 'x' and 'y' properties."); + } + } else { + cerr << "[WARNING] Only 'connector' and 'points' nodes are allowed in 'schematic'.'net'.'wire', others will be ignored." << endl; + } + } } -} + } -// SIZING // -void Circuit::readSizing(xmlNode* node) { + // SIZING // + void Circuit::readSizing(xmlNode* node) { if (readSizingDone) { - cerr << "[WARNING] Only one 'sizing' node is allowed in circuit, others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'sizing' node is allowed in circuit, others will be ignored." << endl; + return; } Sizing* sizing = new Sizing(this); cerr << "** S ** " << node->name << ": " << node->type << endl; xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"instance")) { - readInstanceSizing(node, sizing); - } else if (xmlStrEqual(node->name, (xmlChar*)"equations")) { - readEquations(node, sizing); - } else { - cerr << "[WARNING] Only 'instance' and 'equations' nodes are allowed in 'sizing', others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstanceSizing(node, sizing); + } else if (xmlStrEqual(node->name, (xmlChar*)"equations")) { + readEquations(node, sizing); + } else { + cerr << "[WARNING] Only 'instance' and 'equations' nodes are allowed in 'sizing', others will be ignored." << endl; + } + } } readSizingDone = true; _sizing = sizing; -} + } -void Circuit::readInstanceSizing(xmlNode* node, Sizing* sizing) { + void Circuit::readInstanceSizing(xmlNode* node, Sizing* sizing) { xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* operatorC = xmlGetProp(node, (xmlChar*)"operator"); xmlChar* simulModC = xmlGetProp(node, (xmlChar*)"simulModel"); if (nameC && operatorC && simulModC) { - Name iName ((const char*)nameC); - string opStr ((const char*)operatorC); - transform(opStr.begin(), opStr.end(), opStr.begin(), ::toupper); - Name opName (opStr); - Name simulMod((const char*)simulModC); - Operator* op = sizing->addOperator(iName, opName, simulMod); - xmlNode* child = node->children; - for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"constraint")) { - readConstraint(node, op); - } else { - cerr << "[WARNING] Only 'constraint' nodes are allowed in 'instance' of 'sizing', others will be ignored." << endl; - } - } - } + Name iName ((const char*)nameC); + string opStr ((const char*)operatorC); + transform(opStr.begin(), opStr.end(), opStr.begin(), ::toupper); + Name opName (opStr); + Name simulMod((const char*)simulModC); + Operator* op = sizing->addOperator(iName, opName, simulMod); + xmlNode* child = node->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"constraint")) { + readConstraint(node, op); + } else { + cerr << "[WARNING] Only 'constraint' nodes are allowed in 'instance' of 'sizing', others will be ignored." << endl; + } + } + } } else { - throw OpenChamsException("[ERROR] 'instance' node in 'sizing' must have 'name', 'operator' and 'simulModel' properties."); + throw OpenChamsException("[ERROR] 'instance' node in 'sizing' must have 'name', 'operator' and 'simulModel' properties."); } -} + } -void Circuit::readConstraint(xmlNode* node, Operator* op) { + void Circuit::readConstraint(xmlNode* node, Operator* op) { // attributes of constraint may be : // param ref refParam [factor] // param refEquation [factor] @@ -743,450 +748,545 @@ void Circuit::readConstraint(xmlNode* node, Operator* op) { xmlChar* refEqC = xmlGetProp(node, (xmlChar*)"refEquation"); xmlChar* factorC = xmlGetProp(node, (xmlChar*)"factor"); if (paramC && refC && refParamC) { - Name param ((const char*)paramC); - Name ref ((const char*)refC); - Name refParam ((const char*)refParamC); - double factor = 1.0; - if (factorC) { - factor = ::getValue(factorC); - } - op->addConstraint(param, ref, refParam, factor); + Name param ((const char*)paramC); + Name ref ((const char*)refC); + Name refParam ((const char*)refParamC); + double factor = 1.0; + if (factorC) { + factor = ::getValue(factorC); + } + op->addConstraint(param, ref, refParam, factor); } else if (paramC && refEqC) { - Name param ((const char*)paramC); - Name refEq ((const char*)refEqC); - double factor = 1.0; - if (factorC) { - factor = ::getValue(factorC); - } - op->addConstraint(param, refEq, factor); + Name param ((const char*)paramC); + Name refEq ((const char*)refEqC); + double factor = 1.0; + if (factorC) { + factor = ::getValue(factorC); + } + op->addConstraint(param, refEq, factor); } else { - throw OpenChamsException("[ERROR] 'constraint' node must have 'param, ref, refParam, [factor]' or 'param, refEq, [factor]' properties."); + throw OpenChamsException("[ERROR] 'constraint' node must have 'param, ref, refParam, [factor]' or 'param, refEq, [factor]' properties."); } -} + } -void Circuit::readEquations(xmlNode* node, Sizing* sizing) { + void Circuit::readEquations(xmlNode* node, Sizing* sizing) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"eq")) { - readEquation(node, sizing); - } else { - throw OpenChamsException("[ERROR] Only 'eq' nodes are allowed in 'equations'."); - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"cstr_circuit_level")) + readEquation_CircuitLevel(node, sizing); + else if (xmlStrEqual(node->name, (xmlChar*)"nrc_cstr")) + readEquation_NRC(node, sizing); + else if (xmlStrEqual(node->name, (xmlChar*)"ddps")) + readEquation_DDPs(node, sizing); + else if (xmlStrEqual(node->name, (xmlChar*)"cstr_designer")) + readEquation_DesignerCstr(node, sizing); + else { + throw OpenChamsException("[ERROR] 'cstr_circuit_level', 'nrc_cstr' and 'ddps' nodes are allowed in 'equations'."); + } + } } -} - -void Circuit::readEquation(xmlNode* node, Sizing* sizing) { - xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); - xmlChar* equationC = xmlGetProp(node, (xmlChar*)"equation"); - if (nameC && equationC) { - Name eName ((const char*)nameC); - string eqStr ((const char*)equationC); - sizing->addEquation(eName, eqStr); - } else { - throw OpenChamsException("[ERROR] 'eq' node in 'equations' must have 'name' and 'equation' properties."); + } + + void Circuit::readEquation_CircuitLevel(xmlNode* node, Sizing* sizing) { + if (node->type == XML_ELEMENT_NODE && node->children) { + for (xmlNode* eqNode = node->children ; eqNode ; eqNode = eqNode->next) { + if (eqNode->type == XML_ELEMENT_NODE && xmlStrEqual(eqNode->name, (xmlChar*)"cstr_cl")) { + xmlChar* nameC = xmlGetProp(eqNode, (xmlChar*)"name"); + xmlChar* equationC = xmlGetProp(eqNode, (xmlChar*)"equation"); + if (nameC && equationC) { + Name eName ((const char*)nameC); + string eqStr ((const char*)equationC); + HighLevelCstr* equation = new HighLevelCstr(); + equation->addEquation(eqStr); + sizing->addEquation(eName, (Equation*)(equation)); + } + else + throw OpenChamsException("[ERROR] 'cstr_cl' node in 'equations' must have 'name' and 'equation' properties."); + } + } } -} + } + + void Circuit::readEquation_DesignerCstr(xmlNode* node, Sizing* sizing) { + if (node->type == XML_ELEMENT_NODE && node->children) { + for (xmlNode* eqNode = node->children ; eqNode ; eqNode = eqNode->next) { + if (eqNode->type == XML_ELEMENT_NODE && xmlStrEqual(eqNode->name, (xmlChar*)"cstr_dsg")) { + xmlChar* nameC = xmlGetProp(eqNode, (xmlChar*)"name"); + xmlChar* equationC = xmlGetProp(eqNode, (xmlChar*)"equation"); + if (nameC && equationC) { + Name eName ((const char*)nameC); + string eqStr ((const char*)equationC); + DesignerCstrOC* equation = new DesignerCstrOC(); + equation->addEquation(eqStr); + sizing->addEquation(eName, (Equation*)(equation)); + } + else + throw OpenChamsException("[ERROR] 'cstr_dsg' node in 'equations' must have 'name' and 'equation' properties."); + } + } + } + } + + void Circuit::readEquation_NRC(xmlNode* node, Sizing* sizing) { + // cerr << "NRC not yet managed" << endl; -// LAYOUT // -void Circuit::readLayout(xmlNode* node) { + if (node->type == XML_ELEMENT_NODE && node->children) { + for (xmlNode* eqNode = node->children ; eqNode ; eqNode = eqNode->next) { + if (eqNode->type == XML_ELEMENT_NODE && xmlStrEqual(eqNode->name, (xmlChar*)"nrc")) { + xmlChar* nameC = xmlGetProp(eqNode, (xmlChar*)"name"); + xmlChar* paramC = xmlGetProp(eqNode, (xmlChar*)"param"); + xmlChar* equationC = xmlGetProp(eqNode, (xmlChar*)"equation"); + if (nameC && equationC && paramC) { + Name eName ((const char*)nameC); + string eqStr ((const char*)equationC); + string paramStr ((const char*)paramC); + NRCCstr* equation = new NRCCstr(paramStr); + equation->addEquation(eqStr); + sizing->addEquation(eName, (Equation*)(equation)); + } + else + throw OpenChamsException("[ERROR] 'nrc' node in 'nrc_cstr' must have 'name', 'param' and 'equation' properties."); + } + } + } + + } + + void Circuit::readEquation_DDPs(xmlNode* node, Sizing* sizing) { + // cerr << "DDP not yet managed" << endl; + + if (node->type == XML_ELEMENT_NODE && node->children) { + for (xmlNode* eqNode = node->children ; eqNode ; eqNode = eqNode->next) { + if (eqNode->type == XML_ELEMENT_NODE && xmlStrEqual(eqNode->name, (xmlChar*)"ddp_i")) { + xmlChar* nameC = xmlGetProp(eqNode, (xmlChar*)"name"); + if (nameC) { + Name eName ((const char*)nameC); + DDP* equation = new DDP(); + for(xmlNode* eqNode2 = eqNode->children ; eqNode2 ; eqNode2 = eqNode2->next) { + if (eqNode2->type == XML_ELEMENT_NODE && xmlStrEqual(eqNode2->name, (xmlChar*)"ddp_eq")) { + xmlChar* equationC = xmlGetProp(eqNode2, (xmlChar*)"equation"); + if (equationC) { + string eqStr ((const char*)equationC); + equation->addEquation(eqStr); + } + } + } + sizing->addEquation(eName, (Equation*)(equation)); + } + else + throw OpenChamsException("[ERROR] 'ddp_i' node in 'ddps' must have 'name' property."); + } + } + } + + } + + // ************************************************************************************* + + // LAYOUT // + void Circuit::readLayout(xmlNode* node) { if (readLayoutDone) { - cerr << "[WARNING] Only one 'layout' node is allowed in circuit, others will be ignored." << endl; - return; + cerr << "[WARNING] Only one 'layout' node is allowed in circuit, others will be ignored." << endl; + return; } Layout* layout = new Layout(this); xmlNode* child = node->children; cerr << "** L ** " << node->name << ": " << node->type << endl; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"instance")) { - readInstanceLayout(node, layout); - } else if (xmlStrEqual(node->name, (xmlChar*)"hbtree")) { - readHBTree(node, layout); - } else { - cerr << "[WARNING] Only 'instance' and 'hbtree' nodes are allowed in 'layout' section, others will be ignored." << endl; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstanceLayout(node, layout); + } else if (xmlStrEqual(node->name, (xmlChar*)"hbtree")) { + readHBTree(node, layout); + } else { + cerr << "[WARNING] Only 'instance' and 'hbtree' nodes are allowed in 'layout' section, others will be ignored." << endl; + } + } } readLayoutDone = true; _layout = layout; -} + } -void Circuit::readInstanceLayout(xmlNode* node, Layout* layout) { + void Circuit::readInstanceLayout(xmlNode* node, Layout* layout) { xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* styleC = xmlGetProp(node, (xmlChar*)"style"); if (nameC && styleC) { - Name iName ((const char*)nameC); - Name styleName ((const char*)styleC); - layout->addInstance(iName, styleName); + Name iName ((const char*)nameC); + Name styleName ((const char*)styleC); + layout->addInstance(iName, styleName); } else { - throw OpenChamsException("[ERROR] 'instance' node in 'layout' must have 'name' and 'style' properties."); + throw OpenChamsException("[ERROR] 'instance' node in 'layout' must have 'name' and 'style' properties."); } -} + } -void Circuit::readHBTree(xmlNode* node, Layout* layout) { + void Circuit::readHBTree(xmlNode* node, Layout* layout) { // HBTree node can have only one child (group or bloc) xmlNode* child = node->children; if (child->type == XML_ELEMENT_NODE) { - // create root node - // thanks to readNodeOrBloc - Node* root = readNodeOrBloc(child); - // save root node in layout - layout->setHBTreeRoot(root); + // create root node + // thanks to readNodeOrBloc + Node* root = readNodeOrBloc(child); + // save root node in layout + layout->setHBTreeRoot(root); } -} + } -Node* Circuit::readNodeOrBloc(xmlNode* node, Node* parent) { + Node* Circuit::readNodeOrBloc(xmlNode* node, Node* parent) { // 1 - create Node based on xmlNode* passed as argument if (node->type == XML_ELEMENT_NODE) { - bool isAGroup = xmlStrEqual(node->name, (xmlChar*)"group"); - xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); - xmlChar* posiC = xmlGetProp(node, (xmlChar*)"position"); - if (!nameC) - throw OpenChamsException("[ERROR] 'bloc' and 'group' nodes in 'hbtree' must have at least a 'name' property."); - Node* nodeOC = NULL; - Name name ((const char*)nameC); - Node::Position pos = Node::NONE; - if (posiC) { - string posStr ((const char*)posiC); - if (posStr == "right") pos = Node::RIGHT; - else if (posStr == "top") pos = Node::TOP; - else throw OpenChamsException("[ERROR] 'position' property of 'bloc' and 'group' nodes must be 'right' or 'top'."); - } - if (isAGroup) { - Group* groupOC = new Group(name, pos, parent); - xmlChar* isolatC = xmlGetProp(node, (xmlChar*)"isolation"); - xmlChar* alignC = xmlGetProp(node, (xmlChar*)"align"); - xmlChar* pairedC = xmlGetProp(node, (xmlChar*)"paired"); - if (isolatC) { - string isolation ((const char*)isolatC); - if (isolation == "true") groupOC->setIsolated(true); - else if (isolation == "false") groupOC->setIsolated(false); - else throw OpenChamsException("[ERROR] 'isolation' property of 'group' node must be 'true' or 'false'."); - } - if (alignC) { - string align ((const char*)alignC); - Group::Align galign = Group::NONE; - if (align == "vertical") galign = Group::VERTICAL; - else if (align == "horizontal") galign = Group::HORIZONTAL; - else throw OpenChamsException("[ERROR] 'align' property of 'group' node must be 'vertical' or 'horizontal'."); - groupOC->setAlign(galign); - } - if (pairedC) { - string paired ((const char*)pairedC); - if (paired == "true") groupOC->setPaired(true); - else if (paired == "false") groupOC->setPaired(false); - else throw OpenChamsException("[ERROR] 'paired' property of 'group' node must be 'true' or 'false'."); - } - nodeOC = groupOC; - } else { - nodeOC = new Bloc(name, pos, parent); - } - // 2 - for each children (up to 2) readNodeOrBloc - for (xmlNode* child = node->children; child; child = child->next) { - if (child->type == XML_ELEMENT_NODE) { - Node* childOC = readNodeOrBloc(child, nodeOC); - // 3 - add to returned Node* to current Node* as right or top children (based on its position) - switch(childOC->getPosition()) { - case Node::RIGHT: - nodeOC->setRight(childOC); - break; - case Node::TOP: - nodeOC->setTop(childOC); - break; - case Node::NONE: - if (!isAGroup) - throw OpenChamsException("[ERROR] a 'bloc' or 'group' without position is only allowed directly under a 'group'."); - Group* groupOC = dynamic_cast(nodeOC); - groupOC->setRootNode(childOC); - } - } - } - // 4 - return current Node - return nodeOC; + bool isAGroup = xmlStrEqual(node->name, (xmlChar*)"group"); + xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); + xmlChar* posiC = xmlGetProp(node, (xmlChar*)"position"); + if (!nameC) + throw OpenChamsException("[ERROR] 'bloc' and 'group' nodes in 'hbtree' must have at least a 'name' property."); + Node* nodeOC = NULL; + Name name ((const char*)nameC); + Node::Position pos = Node::NONE; + if (posiC) { + string posStr ((const char*)posiC); + if (posStr == "right") pos = Node::RIGHT; + else if (posStr == "top") pos = Node::TOP; + else throw OpenChamsException("[ERROR] 'position' property of 'bloc' and 'group' nodes must be 'right' or 'top'."); + } + if (isAGroup) { + Group* groupOC = new Group(name, pos, parent); + xmlChar* isolatC = xmlGetProp(node, (xmlChar*)"isolation"); + xmlChar* alignC = xmlGetProp(node, (xmlChar*)"align"); + xmlChar* pairedC = xmlGetProp(node, (xmlChar*)"paired"); + if (isolatC) { + string isolation ((const char*)isolatC); + if (isolation == "true") groupOC->setIsolated(true); + else if (isolation == "false") groupOC->setIsolated(false); + else throw OpenChamsException("[ERROR] 'isolation' property of 'group' node must be 'true' or 'false'."); + } + if (alignC) { + string align ((const char*)alignC); + Group::Align galign = Group::NONE; + if (align == "vertical") galign = Group::VERTICAL; + else if (align == "horizontal") galign = Group::HORIZONTAL; + else throw OpenChamsException("[ERROR] 'align' property of 'group' node must be 'vertical' or 'horizontal'."); + groupOC->setAlign(galign); + } + if (pairedC) { + string paired ((const char*)pairedC); + if (paired == "true") groupOC->setPaired(true); + else if (paired == "false") groupOC->setPaired(false); + else throw OpenChamsException("[ERROR] 'paired' property of 'group' node must be 'true' or 'false'."); + } + nodeOC = groupOC; + } else { + nodeOC = new Bloc(name, pos, parent); + } + // 2 - for each children (up to 2) readNodeOrBloc + for (xmlNode* child = node->children; child; child = child->next) { + if (child->type == XML_ELEMENT_NODE) { + Node* childOC = readNodeOrBloc(child, nodeOC); + // 3 - add to returned Node* to current Node* as right or top children (based on its position) + switch(childOC->getPosition()) { + case Node::RIGHT: + nodeOC->setRight(childOC); + break; + case Node::TOP: + nodeOC->setTop(childOC); + break; + case Node::NONE: + if (!isAGroup) + throw OpenChamsException("[ERROR] a 'bloc' or 'group' without position is only allowed directly under a 'group'."); + Group* groupOC = dynamic_cast(nodeOC); + groupOC->setRootNode(childOC); + } + } + } + // 4 - return current Node + return nodeOC; } return NULL; -} + } -void Circuit::setAbsolutePath(const string filePath) { + void Circuit::setAbsolutePath(const string filePath) { if (filePath[0] == '/') - _absolutePath = filePath; + _absolutePath = filePath; else { - _absolutePath = string(getenv("PWD"))+"/"+filePath; + _absolutePath = string(getenv("PWD"))+"/"+filePath; } size_t found = _absolutePath.find_last_of("/"); _absolutePath = _absolutePath.substr(0, found); -} + } -Circuit* Circuit::readFromFile(const string filePath) { + Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; Circuit* cir = NULL; xmlDoc* doc = xmlReadFile(filePath.c_str(), NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { - string error ("[ERROR] Failed to parse: "); - error += filePath; - throw OpenChamsException(error); - //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")) { - xmlChar* circuitNameC = xmlGetProp(rootElement, (xmlChar*)"name"); - xmlChar* technoNameC = xmlGetProp(rootElement, (xmlChar*)"techno"); + xmlChar* circuitNameC = xmlGetProp(rootElement, (xmlChar*)"name"); + xmlChar* technoNameC = xmlGetProp(rootElement, (xmlChar*)"techno"); - if (circuitNameC && technoNameC) { - Name circuitName ((const char*)circuitNameC); - Name technoName ((const char*)technoNameC); - cir = new Circuit(circuitName, technoName); - } else { - throw OpenChamsException("[ERROR] 'circuit' node must have 'name' and 'techno' properties."); - return NULL; - } - cir->setAbsolutePath(filePath); + if (circuitNameC && technoNameC) { + Name circuitName ((const char*)circuitNameC); + Name technoName ((const char*)technoNameC); + cir = new Circuit(circuitName, technoName); + } else { + throw OpenChamsException("[ERROR] 'circuit' node must have 'name' and 'techno' properties."); + return NULL; + } + cir->setAbsolutePath(filePath); - xmlNode* child = rootElement->children; - for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"subCircuitsPaths")) { - cir->readSubCircuitsPaths(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { - cir->readCircuitParameters(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"simulModels")) { - cir->readSimulModels(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { - cir->readNetList(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { - cir->readSchematic(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { - cir->readSizing(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"layout")) { - cir->readLayout(node); - } - else { - string error("[ERROR] Unknown section "); - error += string((const char*)node->name); - error += " in circuit description."; - throw OpenChamsException(error); - 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*)"subCircuitsPaths")) { + cir->readSubCircuitsPaths(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { + cir->readCircuitParameters(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"simulModels")) { + cir->readSimulModels(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { + cir->readNetList(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { + cir->readSchematic(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { + cir->readSizing(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"layout")) { + cir->readLayout(node); + } + else { + string error("[ERROR] Unknown section "); + error += string((const char*)node->name); + error += " in circuit description."; + throw OpenChamsException(error); + return NULL; + } + } + } } if (!readNetListDone) { - throw OpenChamsException("[ERROR] no section was found in parsed file !"); + throw OpenChamsException("[ERROR] no section was found in parsed file !"); } return cir; -} + } -Netlist* Circuit::createNetlist() { + Netlist* Circuit::createNetlist() { if (_netlist) - throw OpenChamsException("[ERROR] Cannot create two netlists in one circuit."); + throw OpenChamsException("[ERROR] Cannot create two netlists in one circuit."); _netlist = new Netlist(this); if (!_netlist) - throw OpenChamsException("[ERROR] Cannot create netlist."); + throw OpenChamsException("[ERROR] Cannot create netlist."); return _netlist; -} + } -Schematic* Circuit::createSchematic() { + Schematic* Circuit::createSchematic() { if (_schematic) - throw OpenChamsException("[ERROR] Cannot create two scheamtics in one circuit."); + throw OpenChamsException("[ERROR] Cannot create two scheamtics in one circuit."); _schematic = new Schematic(this); if (!_schematic) - throw OpenChamsException("[ERROR] Cannot create schematic."); + throw OpenChamsException("[ERROR] Cannot create schematic."); return _schematic; -} + } -Sizing* Circuit::createSizing() { + Sizing* Circuit::createSizing() { if (_sizing) - throw OpenChamsException("[ERROR] Cannot create two sizings in one circuit."); + throw OpenChamsException("[ERROR] Cannot create two sizings in one circuit."); _sizing = new Sizing(this); if (!_sizing) - throw OpenChamsException("[ERROR] Cannot create sizing."); + throw OpenChamsException("[ERROR] Cannot create sizing."); return _sizing; -} + } -Layout* Circuit::createLayout() { + Layout* Circuit::createLayout() { if (_layout) - throw OpenChamsException("[ERROR] Cannot create two layouts in one circuit."); + throw OpenChamsException("[ERROR] Cannot create two layouts in one circuit."); _layout = new Layout(this); if (!_layout) - throw OpenChamsException("[ERROR] Cannot create layout."); + throw OpenChamsException("[ERROR] Cannot create layout."); return _layout; -} + } -void Circuit::driveHBTree(ofstream& file, Node* node, unsigned indent) { + void Circuit::driveHBTree(ofstream& file, Node* node, unsigned indent) { if (!node) return; for (unsigned i = 0 ; i < indent ; i++) - file << " "; + file << " "; string pos = ""; switch(node->getPosition()) { - case OpenChams::Node::TOP: - pos = "top"; - break; - case OpenChams::Node::RIGHT: - pos = "right"; - break; - default: - break; + case OpenChams::Node::TOP: + pos = "top"; + break; + case OpenChams::Node::RIGHT: + pos = "right"; + break; + default: + break; } Bloc* bloc = dynamic_cast(node); if (bloc) { - file << "getName().getString() << "\""; - if (pos != "") - file << " position=\"" << pos << "\""; - if (bloc->getTop() == NULL && bloc->getRight() == NULL) - file << "/>" << endl; - else { - file << ">" << endl; - driveHBTree(file, bloc->getTop() , indent+1); - driveHBTree(file, bloc->getRight(), indent+1); - for (unsigned i = 0 ; i < indent ; i++) - file << " "; - file << "" << endl; - } - return; + file << "getName().getString() << "\""; + if (pos != "") + file << " position=\"" << pos << "\""; + if (bloc->getTop() == NULL && bloc->getRight() == NULL) + file << "/>" << endl; + else { + file << ">" << endl; + driveHBTree(file, bloc->getTop() , indent+1); + driveHBTree(file, bloc->getRight(), indent+1); + for (unsigned i = 0 ; i < indent ; i++) + file << " "; + file << "" << endl; + } + return; } Group* group = dynamic_cast(node); if (group) { - string align = ""; - switch(group->getAlign()) { - case OpenChams::Group::VERTICAL: - align = "vertical"; - break; - case OpenChams::Group::HORIZONTAL: - align = "horizontal"; - break; - default: - break; - } - file << "getName().getString() << "\""; - if (pos != "") file << " position=\"" << pos << "\""; - if (align != "") file << " align=\"" << align << "\""; - if (group->isIsolated()) file << " isolated=\"true\""; - if (group->isPaired()) file << " paired=\"true\""; - file << ">" << endl; - driveHBTree(file, group->getRootNode(), indent+1); - driveHBTree(file, group->getTop() , indent+1); - driveHBTree(file, group->getRight() , indent+1); - for (unsigned i = 0 ; i < indent ; i++) - file << " "; - file << "" << endl; - return; + string align = ""; + switch(group->getAlign()) { + case OpenChams::Group::VERTICAL: + align = "vertical"; + break; + case OpenChams::Group::HORIZONTAL: + align = "horizontal"; + break; + default: + break; + } + file << "getName().getString() << "\""; + if (pos != "") file << " position=\"" << pos << "\""; + if (align != "") file << " align=\"" << align << "\""; + if (group->isIsolated()) file << " isolated=\"true\""; + if (group->isPaired()) file << " paired=\"true\""; + file << ">" << endl; + driveHBTree(file, group->getRootNode(), indent+1); + driveHBTree(file, group->getTop() , indent+1); + driveHBTree(file, group->getRight() , indent+1); + for (unsigned i = 0 ; i < indent ; i++) + file << " "; + file << "" << endl; + return; } -} + } -bool Circuit::writeToFile(string filePath) { + bool Circuit::writeToFile(string filePath) { ofstream file; file.open(filePath.c_str()); if (!file.is_open()) { - string error("[ERROR] Cannot open file "); - error += filePath; - error += " for writing."; - throw OpenChamsException(error); + string error("[ERROR] Cannot open file "); + error += filePath; + error += " for writing."; + throw OpenChamsException(error); } // checks before do anything if (!_netlist) { - //cerr << "no netlist" << endl; cerr.flush(); - throw OpenChamsException("[ERROR] Cannot writeToFile since no netlist is defined !"); - //return false; + //cerr << "no netlist" << endl; cerr.flush(); + throw OpenChamsException("[ERROR] Cannot writeToFile since no netlist is defined !"); + //return false; } if (_netlist->hasNoInstances()) { - //cerr << "no instances" << endl; cerr.flush(); - throw OpenChamsException("[ERROR] Cannot writeToFile since no instance is defined in netlist !"); - //return false; + //cerr << "no instances" << endl; cerr.flush(); + throw OpenChamsException("[ERROR] Cannot writeToFile since no instance is defined in netlist !"); + //return false; } if (_netlist->hasNoNets()) { - //cerr << "no nets" << endl; cerr.flush(); - throw OpenChamsException("[ERROR] Cannot writeToFile since no net is defined in netlist !"); - //return false; + //cerr << "no nets" << endl; cerr.flush(); + throw OpenChamsException("[ERROR] Cannot writeToFile since no net is defined in netlist !"); + //return false; } file << "" << endl << "" << endl; if (_subCircuitsPaths.size() != 0) { - file << " " << endl; - for (size_t i = 0 ; i < _subCircuitsPaths.size() ; i++ ) { - file << " " << endl; - } - file << " " << endl; + file << " " << endl; + for (size_t i = 0 ; i < _subCircuitsPaths.size() ; i++ ) { + file << " " << endl; + } + file << " " << endl; } if (!_params.isEmpty()) { - file << " " << endl; - for (map::const_iterator it = _params.getValues().begin() ; it != _params.getValues().end() ; ++it) { - file << " " << endl; - } - for (map::const_iterator it = _params.getEqValues().begin() ; it != _params.getEqValues().end() ; ++it) { - file << " " << endl; - } - file << " " << endl; + file << " " << endl; + for (map::const_iterator it = _params.getValues().begin() ; it != _params.getValues().end() ; ++it) { + file << " " << endl; + } + cerr << "_params.getValues().size() = " << _params.getValues().size() << endl; + cerr << "_params.getEqValues().size() = " << _params.getEqValues().size() << endl; + for (map::const_iterator it2 = _params.getEqValues().begin() ; it2 != _params.getEqValues().end() ; ++it2) { + file << " " << endl; + } + file << " " << endl; } file << " " << endl << " " << endl; vector instances = _netlist->getInstances(); sort(instances.begin(), instances.end(), InstanceNameSort); // sort based on instances' names for (vector::iterator it = instances.begin() ; it != instances.end() ; ++it) { - Instance* inst = (*it); - Device* dev = dynamic_cast(inst); - if (inst->hasNoConnectors()) { - string error("[ERROR] Cannot writeToFile since instance ("); - error += inst->getName().getString(); - error += ") has no connectors !"; - throw OpenChamsException(error); - //return false; - } - if (dev && dev->hasNoTransistors()) { - string error("[ERROR] Cannot writeToFile since device instance ("); - error += dev->getName().getString(); - error += ") has no transistors !"; - throw OpenChamsException(error); - } - if (dev) { - string sourceBulkStr = (dev->isSourceBulkConnected()) ? "True" : "False"; - file << " getName().getString() << "\" model=\"" << dev->getModel().getString() << "\" mostype=\"" << dev->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\" order=\"" << dev->getOrder() << "\">" << endl; - } else { - file << " getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" order=\"" << inst->getOrder() << "\">" << endl; - } - file << " " << endl; - for (map::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { - file << " " << endl; - } - file << " " << endl; - if (dev) { - file << " " << endl; - for (vector::const_iterator it = dev->getTransistors().begin() ; it != dev->getTransistors().end() ; ++it ) { - Transistor* tr = (*it); - file << " getName().getString() << "\">" << endl - << " getGate().getString() << "\" source=\"" << tr->getSource().getString() << "\" drain=\"" << tr->getDrain().getString() << "\" bulk=\"" << tr->getBulk().getString() << "\"/>" << endl - << " " << endl; - } - file << " " << endl; - } - if (!inst->getParameters().isEmpty()) { - Parameters params = inst->getParameters(); - file << " " << endl; - for (map::const_iterator it = params.getValues().begin() ; it != params.getValues().end() ; ++it) { - file << " " << endl; - } - file << " " << endl; - } - file << " " << endl; + Instance* inst = (*it); + Device* dev = dynamic_cast(inst); + if (inst->hasNoConnectors()) { + string error("[ERROR] Cannot writeToFile since instance ("); + error += inst->getName().getString(); + error += ") has no connectors !"; + throw OpenChamsException(error); + //return false; + } + if (dev && dev->hasNoTransistors()) { + string error("[ERROR] Cannot writeToFile since device instance ("); + error += dev->getName().getString(); + error += ") has no transistors !"; + throw OpenChamsException(error); + } + if (dev) { + string sourceBulkStr = (dev->isSourceBulkConnected()) ? "True" : "False"; + file << " getName().getString() << "\" model=\"" << dev->getModel().getString() << "\" mostype=\"" << dev->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\" order=\"" << dev->getOrder() << "\">" << endl; + } else { + file << " getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" order=\"" << inst->getOrder() << "\">" << endl; + } + file << " " << endl; + for (map::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { + file << " " << endl; + } + file << " " << endl; + if (dev) { + file << " " << endl; + for (vector::const_iterator it = dev->getTransistors().begin() ; it != dev->getTransistors().end() ; ++it ) { + Transistor* tr = (*it); + file << " getName().getString() << "\">" << endl + << " getGate().getString() << "\" source=\"" << tr->getSource().getString() << "\" drain=\"" << tr->getDrain().getString() << "\" bulk=\"" << tr->getBulk().getString() << "\"/>" << endl + << " " << endl; + } + file << " " << endl; + } + if (!inst->getParameters().isEmpty()) { + Parameters params = inst->getParameters(); + file << " " << endl; + for (map::const_iterator it = params.getValues().begin() ; it != params.getValues().end() ; ++it) { + file << " " << endl; + } + for(map::const_iterator it = params.getEqValues().begin() ; it != params.getEqValues().end() ; ++it) { + file << " " << endl; + } + file << " " << endl; + } + file << " " << endl; } file << " " << endl << " " << endl; @@ -1194,129 +1294,171 @@ bool Circuit::writeToFile(string filePath) { vector nets = _netlist->getNets(); 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->hasNoConnections()) { - string error("[ERROR] Cannot writeToFile since net ("); - error += net->getName().getString(); - error += ") has no connectors !"; - throw OpenChamsException(error); - //return false; - } - if (!net->hasNoPorts() || !net->hasNoWires()) - schematicNets = true; - string externStr = (net->isExternal()) ? "True" : "False"; - file << " getName().getString() << "\" type=\"" << net->getType().getString() << "\" isExternal=\"" << externStr << "\">" << endl; - vector connections = net->getConnections(); - sort(connections.begin(), connections.end(), ConnectionsSort); - for (vector::iterator it = connections.begin() ; it != connections.end() ; ++it) { - file << " getInstanceName().getString() << "\" name=\"" << (*it)->getConnectorName().getString() << "\"/>" << endl; - } - file << " " << endl; + Net* net = (*it); + if (net->hasNoConnections()) { + string error("[ERROR] Cannot writeToFile since net ("); + error += net->getName().getString(); + error += ") has no connectors !"; + throw OpenChamsException(error); + //return false; + } + if (!net->hasNoPorts() || !net->hasNoWires()) + schematicNets = true; + string externStr = (net->isExternal()) ? "True" : "False"; + file << " getName().getString() << "\" type=\"" << net->getType().getString() << "\" isExternal=\"" << externStr << "\">" << endl; + vector connections = net->getConnections(); + sort(connections.begin(), connections.end(), ConnectionsSort); + for (vector::iterator it = connections.begin() ; it != connections.end() ; ++it) { + file << " getInstanceName().getString() << "\" name=\"" << (*it)->getConnectorName().getString() << "\"/>" << endl; + } + file << " " << endl; } file << " " << endl; file << " " << endl; if (_schematic && !_schematic->hasNoInstances()) { - file << " " << endl; - for (map::const_iterator it = _schematic->getInstances().begin() ; it != _schematic->getInstances().end(); ++it ) { - Schematic::Infos* infos = (*it).second; - file << " getX() << "\" y=\"" << infos->getY() << "\" orient=\"" << infos->getOrientation().getString() << "\"/>" << endl; - } - if (schematicNets) { - for (size_t i = 0 ; i < nets.size() ; i++) { - Net* net = nets[i]; - if (net->hasNoPorts() && net->hasNoWires()) - continue; - file << " getName().getString() << "\">" << endl; - for (size_t j = 0 ; j < net->getPorts().size() ; j++) { - Port* port = net->getPorts()[j]; - if (!port) - continue; - file << " getType().getString() << "\" idx=\"" << port->getIndex() << "\" x=\"" << port->getX() << "\" y=\"" << port->getY() << "\" orient=\"" << port->getOrientation().getString() << "\"/>" << endl; - } - for (size_t j = 0 ; j < net->getWires().size() ; j++) { - Wire* wire = net->getWires()[j]; - file << " " << endl; - WirePoint* start = wire->getStartPoint(); - WirePoint* end = wire->getEndPoint(); - // start point - if (dynamic_cast(start)) { - InstancePoint* iP = static_cast(start); - file << " getName().getString() << "\" plug=\"" << iP->getPlug().getString() << "\"/>" << endl; - } else if (dynamic_cast(start)) { - PortPoint* pP = static_cast(start); - file << " getIndex() << "\"/>" << endl; - } else { - throw OpenChamsException("[ERROR] Wire start point is nor an InstancePoint nor a PortPoint."); - } - // intermediate points - for (size_t k = 0 ; k < wire->getIntermediatePoints().size() ; k++) { - IntermediatePoint* iP = wire->getIntermediatePoints()[k]; - file << " getX() << "\" y=\"" << iP->getY() << "\"/>" << endl; - } - // end point - if (dynamic_cast(end)) { - InstancePoint* iP = static_cast(end); - file << " getName().getString() << "\" plug=\"" << iP->getPlug().getString() << "\"/>" << endl; - } else if (dynamic_cast(end)) { - PortPoint* pP = static_cast(end); - file << " getIndex() << "\"/>" << endl; - } else { - throw OpenChamsException("[ERROR] Wire end point is nor an InstancePoint nor a PortPoint."); - } - file << " " << endl; - } - file << " " << endl; - } - } - file << " " << endl; + file << " " << endl; + for (map::const_iterator it = _schematic->getInstances().begin() ; it != _schematic->getInstances().end(); ++it ) { + Schematic::Infos* infos = (*it).second; + file << " getX() << "\" y=\"" << infos->getY() << "\" orient=\"" << infos->getOrientation().getString() << "\"/>" << endl; + } + if (schematicNets) { + for (size_t i = 0 ; i < nets.size() ; i++) { + Net* net = nets[i]; + if (net->hasNoPorts() && net->hasNoWires()) + continue; + file << " getName().getString() << "\">" << endl; + for (size_t j = 0 ; j < net->getPorts().size() ; j++) { + Port* port = net->getPorts()[j]; + if (!port) + continue; + file << " getType().getString() << "\" idx=\"" << port->getIndex() << "\" x=\"" << port->getX() << "\" y=\"" << port->getY() << "\" orient=\"" << port->getOrientation().getString() << "\"/>" << endl; + } + for (size_t j = 0 ; j < net->getWires().size() ; j++) { + Wire* wire = net->getWires()[j]; + file << " " << endl; + WirePoint* start = wire->getStartPoint(); + WirePoint* end = wire->getEndPoint(); + // start point + if (dynamic_cast(start)) { + InstancePoint* iP = static_cast(start); + file << " getName().getString() << "\" plug=\"" << iP->getPlug().getString() << "\"/>" << endl; + } else if (dynamic_cast(start)) { + PortPoint* pP = static_cast(start); + file << " getIndex() << "\"/>" << endl; + } else { + throw OpenChamsException("[ERROR] Wire start point is nor an InstancePoint nor a PortPoint."); + } + // intermediate points + for (size_t k = 0 ; k < wire->getIntermediatePoints().size() ; k++) { + IntermediatePoint* iP = wire->getIntermediatePoints()[k]; + file << " getX() << "\" y=\"" << iP->getY() << "\"/>" << endl; + } + // end point + if (dynamic_cast(end)) { + InstancePoint* iP = static_cast(end); + file << " getName().getString() << "\" plug=\"" << iP->getPlug().getString() << "\"/>" << endl; + } else if (dynamic_cast(end)) { + PortPoint* pP = static_cast(end); + file << " getIndex() << "\"/>" << endl; + } else { + throw OpenChamsException("[ERROR] Wire end point is nor an InstancePoint nor a PortPoint."); + } + file << " " << endl; + } + file << " " << endl; + } + } + file << " " << endl; } + + // SIZING (modified by Farakh) *************************************************************** + if(_sizing && (!_sizing->hasNoOperators() || !_sizing->hasNoEquations()) ) + file << " " << endl; if (_sizing && !_sizing->hasNoOperators()) { - file << " " << endl; - for (map::const_iterator it = _sizing->getOperators().begin() ; it != _sizing->getOperators().end() ; ++it) { - Operator* op = (*it).second; - string opName = op->getName().getString(); - transform(opName.begin(), opName.end(), opName.begin(), ::toupper); - file << " getSimulModel().getString() << "\">" << endl; - if (!op->hasNoConstraints()) { - for (map::const_iterator cit = op->getConstraints().begin() ; cit != op->getConstraints().end() ; ++cit) { - Operator::Constraint* cn = (*cit).second; - Name ref = cn->getRef(); - if (ref == Name("")) { - file << " getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; - } else { - file << " getRef().getString() << "\" refParam=\"" << cn->getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; - } - } - } - file << " " << endl; - } - if (!_sizing->hasNoEquations()) { - file << " " << endl; - for (map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { - file << " " << endl; - } - file << " " << endl; - } - file << " " << endl; + // file << " " << endl; + for (map::const_iterator it = _sizing->getOperators().begin() ; it != _sizing->getOperators().end() ; ++it) { + Operator* op = (*it).second; + string opName = op->getName().getString(); + transform(opName.begin(), opName.end(), opName.begin(), ::toupper); + file << " getSimulModel().getString() << "\">" << endl; + if (!op->hasNoConstraints()) { + for (map::const_iterator cit = op->getConstraints().begin() ; cit != op->getConstraints().end() ; ++cit) { + Operator::Constraint* cn = (*cit).second; + Name ref = cn->getRef(); + if (ref == Name("")) { + file << " getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; + } else { + file << " getRef().getString() << "\" refParam=\"" << cn->getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; + } + } + } + file << " " << endl; + } } + // EQUATIONS + if (_sizing && !_sizing->hasNoEquations()) { + file << " " << endl; + // for (map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) + // file << " " << endl; + file << " " << endl; + for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { + if(dynamic_cast((*it).second)) + file << " getEquationStr()[0] << "\"/>" << endl; + } + file << " " << endl; + + file << " " << endl; + for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { + if(dynamic_cast((*it).second)) + file << " getEquationStr()[0] << "\"/>" << endl; + } + file << " " << endl; + + file << " " << endl; + for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { + if(dynamic_cast((*it).second)) { + NRCCstr* nrcCstr = (NRCCstr*)((*it).second); + file << " getVoltage() << "\" equation=\"" << (*it).second->getEquationStr()[0] << "\"/>" << endl; + } + } + file << " " << endl; + + file << " " << endl; + for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { + if(dynamic_cast((*it).second)) { + file << " " << endl; + for(map::const_iterator it2 = (*it).second->getEquationStr().begin(); it2!=(*it).second->getEquationStr().end(); ++it2) + file << " " << endl; + file << " " << endl; + } + } + file << " " << endl; + + + file << " " << endl; + } + if(_sizing && (!_sizing->hasNoOperators() || !_sizing->hasNoEquations()) ) + file << " " << endl; + // ******************************************************************************************* + if (_layout) { - file << " " << endl; - if (!_layout->hasNoInstance()) { - for (map::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) { - file << " " << endl; - } - } - if (Node* root = _layout->getHBTreeRoot()) { - file << " " << endl; - driveHBTree(file, root, 3); - file << " " << endl; - } - file << " " << endl; + file << " " << endl; + if (!_layout->hasNoInstance()) { + for (map::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) { + file << " " << endl; + } + } + if (Node* root = _layout->getHBTreeRoot()) { + file << " " << endl; + driveHBTree(file, root, 3); + file << " " << endl; + } + file << " " << endl; } file << "" << endl; file.close(); - return true; -} + return true; + } } diff --git a/vlsisapd/src/openChams/src/DDP.cpp b/vlsisapd/src/openChams/src/DDP.cpp new file mode 100644 index 00000000..d7222572 --- /dev/null +++ b/vlsisapd/src/openChams/src/DDP.cpp @@ -0,0 +1,32 @@ +/* + * DDP.cpp + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +#include + +using namespace std; + +#include "vlsisapd/openChams/DDP.h" + +namespace OpenChams { + DDP::DDP() + : Equation() + {} + + // This function prints all equations + void DDP::printEquations() { + map::iterator it; + cerr << "Printing equations of a DDP : " << endl; + for(it=_equations.begin(); it!=_equations.end(); ++it) { + cerr << (*it).first << "\t" << (*it).second << endl; + } + } + + +} // namespace diff --git a/vlsisapd/src/openChams/src/DesignerCstrOC.cpp b/vlsisapd/src/openChams/src/DesignerCstrOC.cpp new file mode 100644 index 00000000..f77937c1 --- /dev/null +++ b/vlsisapd/src/openChams/src/DesignerCstrOC.cpp @@ -0,0 +1,31 @@ +/* + * DesignerCstrOC.cpp + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +#include + +using namespace std; + +#include "vlsisapd/openChams/DesignerCstrOC.h" + +namespace OpenChams { + DesignerCstrOC::DesignerCstrOC() + : Equation() + {} + + // This function prints all equations + void DesignerCstrOC::printEquations() { + map::iterator it; + cerr << "Printing equations of a DesignerCstrOC : " << endl; + for(it=_equations.begin(); it!=_equations.end(); ++it) { + cerr << (*it).first << "\t" << (*it).second << endl; + } + } + +} // namespace diff --git a/vlsisapd/src/openChams/src/Equation.cpp b/vlsisapd/src/openChams/src/Equation.cpp new file mode 100644 index 00000000..bf56eacb --- /dev/null +++ b/vlsisapd/src/openChams/src/Equation.cpp @@ -0,0 +1,25 @@ +/* + * Equation.cpp + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +using namespace std; + +#include "vlsisapd/openChams/Equation.h" + +namespace OpenChams { + Equation::Equation() + : _equations() + // , _paramsInEquation() + {} + + void Equation::addEquation(std::string eq) { + _equations[_equations.size()] = eq; + } + +} // namespace diff --git a/vlsisapd/src/openChams/src/HighLevelCstr.cpp b/vlsisapd/src/openChams/src/HighLevelCstr.cpp new file mode 100644 index 00000000..a7e622ff --- /dev/null +++ b/vlsisapd/src/openChams/src/HighLevelCstr.cpp @@ -0,0 +1,31 @@ +/* + * HighLevelCstr.cpp + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +#include + +using namespace std; + +#include "vlsisapd/openChams/HighLevelCstr.h" + +namespace OpenChams { + HighLevelCstr::HighLevelCstr() + : Equation() + {} + + // This function prints all equations + void HighLevelCstr::printEquations() { + map::iterator it; + cerr << "Printing equations of a HighLevelCstr : " << endl; + for(it=_equations.begin(); it!=_equations.end(); ++it) { + cerr << (*it).first << "\t" << (*it).second << endl; + } + } + +} // namespace diff --git a/vlsisapd/src/openChams/src/NRCCstr.cpp b/vlsisapd/src/openChams/src/NRCCstr.cpp new file mode 100644 index 00000000..abcc6fef --- /dev/null +++ b/vlsisapd/src/openChams/src/NRCCstr.cpp @@ -0,0 +1,33 @@ +/* + * NRCCstr.cpp + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +#include + +using namespace std; + +#include "vlsisapd/openChams/NRCCstr.h" + +namespace OpenChams { + NRCCstr::NRCCstr(string controlVoltage) + : Equation() + , _controlVoltage(controlVoltage) + {} + + // This function prints all equations + void NRCCstr::printEquations() { + map::iterator it; + cerr << "Printing equations of a NRCCstr : " << endl; + cerr << "Control voltage = " << _controlVoltage << endl; + for(it=_equations.begin(); it!=_equations.end(); ++it) { + cerr << (*it).first << "\t" << (*it).second << endl; + } + } + +} // namespace diff --git a/vlsisapd/src/openChams/src/Parameters.cpp b/vlsisapd/src/openChams/src/Parameters.cpp index bae35477..246f9f7e 100644 --- a/vlsisapd/src/openChams/src/Parameters.cpp +++ b/vlsisapd/src/openChams/src/Parameters.cpp @@ -59,6 +59,7 @@ void Parameters::addParameter(Name name, string eqStr) { throw OpenChamsException(error); } _paramsEq[name] = eqStr; + cerr << "987* _paramsEq.size() = " << _paramsEq.size() << endl; } } // namespace diff --git a/vlsisapd/src/openChams/src/PyOpenChams.cpp b/vlsisapd/src/openChams/src/PyOpenChams.cpp index 2eabf25b..a59f9f2c 100644 --- a/vlsisapd/src/openChams/src/PyOpenChams.cpp +++ b/vlsisapd/src/openChams/src/PyOpenChams.cpp @@ -299,6 +299,7 @@ BOOST_PYTHON_MODULE(OPENCHAMS) { ; } // end operatorScope + /* // map wrapping for OpenChams::Sizing STL_MAP_WRAPPING_PTR(Name, Operator*, "OperatorsMap") // class OpenChams::Sizing @@ -313,6 +314,7 @@ BOOST_PYTHON_MODULE(OPENCHAMS) { .def("getEquations", &Sizing::getEquations, return_internal_reference<>()) .def("getOperators", &Sizing::getOperators, return_internal_reference<>()) ; + */ // map wrapping for OpenChams::Layout STL_MAP_WRAPPING(Name, Name, "LayoutInstancesMap") diff --git a/vlsisapd/src/openChams/src/Sizing.cpp b/vlsisapd/src/openChams/src/Sizing.cpp index 88283673..2bf6b0d6 100644 --- a/vlsisapd/src/openChams/src/Sizing.cpp +++ b/vlsisapd/src/openChams/src/Sizing.cpp @@ -13,6 +13,7 @@ using namespace std; #include "vlsisapd/openChams/Sizing.h" #include "vlsisapd/openChams/Circuit.h" #include "vlsisapd/openChams/Operator.h" +#include "vlsisapd/openChams/Equation.h" #include "vlsisapd/openChams/OpenChamsException.h" namespace OpenChams { @@ -31,8 +32,8 @@ Operator* Sizing::addOperator(Name instanceName, Name operatorName, Name simulMo return op; } -void Sizing::addEquation(Name equationName, string equation) { - map::iterator it = _equations.find(equationName); +void Sizing::addEquation(Name equationName, Equation* equation) { + map::iterator it = _equations.find(equationName); if (it != _equations.end()) { string error("[ERROR] Cannot set several equations with the same name in 'sizing' ("); error += equationName.getString(); diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h index dbdcd82d..08c436cf 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h @@ -91,8 +91,13 @@ class Circuit { void readSizing(xmlNode*); void readInstanceSizing(xmlNode*, Sizing*); void readConstraint(xmlNode*, Operator*); + void readEquations(xmlNode*, Sizing*); - void readEquation(xmlNode*, Sizing*); + void readEquation_CircuitLevel(xmlNode*, Sizing*); + void readEquation_NRC(xmlNode*, Sizing*); + void readEquation_DDPs(xmlNode*, Sizing*); + void readEquation_DesignerCstr(xmlNode*, Sizing*); + void readLayout(xmlNode*); void readInstanceLayout(xmlNode*, Layout*); void readHBTree(xmlNode*, Layout*); diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/DDP.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/DDP.h new file mode 100644 index 00000000..d27ada63 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/DDP.h @@ -0,0 +1,24 @@ +/* + * DDP.h + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_DDP_H__ +#define __OPENCHAMS_DDP_H__ + +#include "vlsisapd/openChams/Equation.h" + +namespace OpenChams { + class DDP : public Equation { + public: + DDP(); + + virtual void printEquations(); + }; + +} // namespace +#endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/DesignerCstrOC.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/DesignerCstrOC.h new file mode 100644 index 00000000..6b538601 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/DesignerCstrOC.h @@ -0,0 +1,24 @@ +/* + * DesignerCstrOC.h + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_DESIGNERCSTROC_H__ +#define __OPENCHAMS_DESIGNERCSTROC_H__ + +#include "vlsisapd/openChams/Equation.h" + +namespace OpenChams { + class DesignerCstrOC : public Equation { + public: + DesignerCstrOC(); + + virtual void printEquations(); + }; + +} // namespace +#endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Equation.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Equation.h new file mode 100644 index 00000000..624fea54 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Equation.h @@ -0,0 +1,34 @@ +/* + * Equation.h + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_EQUATION_H__ +#define __OPENCHAMS_EQUATION_H__ + +#include +#include +//using namespace std; + +namespace OpenChams { + class Equation { + public: + Equation(); + + void addEquation(std::string eq); + inline std::map& getEquationStr(); + virtual void printEquations() = 0; + + protected: + std::map _equations; // this map contains the equation(s) + // std::vector _paramsInEquation; // + }; + + inline std::map& Equation::getEquationStr() {return _equations;} + +} // namespace +#endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/HighLevelCstr.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/HighLevelCstr.h new file mode 100644 index 00000000..4233eeda --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/HighLevelCstr.h @@ -0,0 +1,24 @@ +/* + * HighLevelCstr.h + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_HIGHLEVELCSTR_H__ +#define __OPENCHAMS_HIGHLEVELCSTR_H__ + +#include "vlsisapd/openChams/Equation.h" + +namespace OpenChams { + class HighLevelCstr : public Equation { + public: + HighLevelCstr(); + + virtual void printEquations(); + }; + +} // namespace +#endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/NRCCstr.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/NRCCstr.h new file mode 100644 index 00000000..8cdf0602 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/NRCCstr.h @@ -0,0 +1,33 @@ +/* + * NRCCstr.h + * openChams + * + * Created by Farakh JAVID on 25/10/2011. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_NRCCSTR_H__ +#define __OPENCHAMS_NRCCSTR_H__ + +#include "vlsisapd/openChams/Equation.h" + +namespace OpenChams { + class NRCCstr : public Equation { + public: + NRCCstr(string controlVoltage); + + inline void setVoltage(std::string s); + inline std::string getVoltage(); + + virtual void printEquations(); + + private: + std::string _controlVoltage; + }; + + inline void NRCCstr::setVoltage(std::string s) {_controlVoltage = s;} + inline std::string NRCCstr::getVoltage() {return _controlVoltage;} + +} // namespace +#endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Sizing.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Sizing.h index 7207cf69..eba5d2ec 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Sizing.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Sizing.h @@ -13,32 +13,40 @@ #include namespace OpenChams { -class Name; -class Circuit; -class Operator; + class Name; + class Circuit; + class Operator; + class Equation; + // class HighLevelCstr; + // class NRCCstr; + // class DDP; -class Sizing { - public: - Sizing(Circuit*); - - Operator* addOperator(Name instanceName, Name operatorName, Name simulModel); - void addEquation(Name equationName, std::string equation); - - inline bool hasNoOperators(); - inline bool hasNoEquations(); - inline const std::map& getOperators(); - inline const std::map& getEquations(); - - private: - Circuit* _circuit; - std::map _operators; // instanceName <-> operator - std::map _equations; // equationName <-> equation (string) - }; + class Sizing { + public: + Sizing(Circuit*); - inline bool Sizing::hasNoOperators() { return (_operators.size() == 0) ? true : false; }; - inline bool Sizing::hasNoEquations() { return (_equations.size() == 0) ? true : false; }; - inline const std::map& Sizing::getOperators() { return _operators; }; - inline const std::map& Sizing::getEquations() { return _equations; }; + Operator* addOperator(Name instanceName, Name operatorName, Name simulModel); + + // void addEquation(Name equationName, HighLevelCstr*); + // void addEquation(Name equationName, NRCCstr*); + // void addEquation(Name equationName, DDP*); + void addEquation(Name equationName, Equation*); + + inline bool hasNoOperators(); + inline bool hasNoEquations(); + inline const std::map& getOperators(); + inline const std::map& getEquations(); + + private: + Circuit* _circuit; + std::map _operators; // instanceName <-> operator + std::map _equations; // equationName <-> equation (string) + }; + + inline bool Sizing::hasNoOperators() { return (_operators.size() == 0) ? true : false; }; + inline bool Sizing::hasNoEquations() { return (_equations.size() == 0) ? true : false; }; + inline const std::map& Sizing::getOperators() { return _operators; }; + inline const std::map& Sizing::getEquations() { return _equations; }; } // namespace #endif