diff --git a/vlsisapd/openChams/CMakeLists.txt b/vlsisapd/openChams/CMakeLists.txt index 75b581b9..5760edbd 100644 --- a/vlsisapd/openChams/CMakeLists.txt +++ b/vlsisapd/openChams/CMakeLists.txt @@ -1,7 +1,7 @@ INCLUDE_DIRECTORIES(${CHAMS_SOURCE_DIR}/openChams ${LIBXML2_INCLUDE_DIR}) -SET ( includes Circuit.h Netlist.h Instance.h Net.h Name.h Parameters.h Schematic.h OpenChamsException.h ) -SET ( cpps Circuit.cpp Netlist.cpp Instance.cpp Net.cpp Name.cpp Parameters.cpp Schematic.cpp ) +SET ( includes Circuit.h Netlist.h Instance.h Net.h Name.h Operator.h Parameters.h Schematic.h Sizing.h OpenChamsException.h ) +SET ( cpps Circuit.cpp Netlist.cpp Instance.cpp Net.cpp Name.cpp Operator.cpp Parameters.cpp Schematic.cpp Sizing.cpp ) ADD_LIBRARY(openChams ${cpps}) diff --git a/vlsisapd/openChams/Circuit.cpp b/vlsisapd/openChams/Circuit.cpp index 8fba85dd..f028bc5a 100644 --- a/vlsisapd/openChams/Circuit.cpp +++ b/vlsisapd/openChams/Circuit.cpp @@ -34,6 +34,7 @@ static bool readNetListDone = false; static bool readInstancesDone = false; static bool readNetsDone = false; static bool readSchematicDone = false; +static bool readSizingDone = false; Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL) { readCircuitParametersDone = false; @@ -41,6 +42,7 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis readInstancesDone = false; readNetsDone = false; readSchematicDone = false; + readSizingDone = false; } void Circuit::check_uppercase(string& str, vector& compares, string message) { @@ -78,7 +80,18 @@ Name Circuit::readParameter(xmlNode* node, double& value) { return name; } else { throw OpenChamsException("[ERROR] 'parameter' node must have 'name' and 'value' properties."); - //return Name(""); + } +} + +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; + } else { + throw OpenChamsException("[ERROR] 'parameterEq' node must have 'name' and 'equation' properties."); } } @@ -106,8 +119,13 @@ void Circuit::readCircuitParameters(xmlNode* node) { 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' nodes are authorized under 'parameters' node." << endl; + cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'parameters' node." << endl; return; } } @@ -223,6 +241,14 @@ void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) { 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; } } } @@ -352,6 +378,111 @@ void Circuit::readInstanceSchematic(xmlNode* node, Schematic* schematic) { throw OpenChamsException("[ERROR] 'instance' node in 'schematic' must have 'name', 'x', 'y' and 'sym' properties."); } } + +void Circuit::readSizing(xmlNode* node) { + if (readSizingDone) { + cerr << "[WARNING] Only one 'sizing' node is allowed in circuit, others will be ignored." << endl; + return; + } + + Sizing* sizing = new Sizing(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")) { + 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) { + xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); + xmlChar* operatorC = xmlGetProp(node, (xmlChar*)"operator"); + xmlChar* simulModC = xmlGetProp(node, (xmlChar*)"simulModel"); + xmlChar* orderC = xmlGetProp(node, (xmlChar*)"callOrder"); + if (nameC && operatorC && simulModC && orderC) { + Name iName ((const char*)nameC); + Name opName ((const char*)operatorC); + Name simulMod((const char*)simulModC); + unsigned callOrder = ::getValue(orderC); + Operator* op = sizing->addOperator(iName, opName, simulMod, callOrder); + 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', 'simulModel' and 'callOrder' properties."); + } +} + +void Circuit::readConstraint(xmlNode* node, Operator* op) { + // attributes of constraint may be : + // param ref refParam [factor] + // param refEquation [factor] + xmlChar* paramC = xmlGetProp(node, (xmlChar*)"param"); + xmlChar* refC = xmlGetProp(node, (xmlChar*)"ref"); + xmlChar* refParamC = xmlGetProp(node, (xmlChar*)"refParam"); + 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); + } 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); + } else { + throw OpenChamsException("[ERROR] 'constraint' node must have 'param, ref, refParam, [factor]' or 'param, refEq, [factor]' properties."); + } +} +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'."); + } + } + } +} + +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."); + } +} Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; @@ -390,6 +521,9 @@ Circuit* Circuit::readFromFile(const string filePath) { if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { cir->readSchematic(node); } + if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { + cir->readSizing(node); + } } } } @@ -426,6 +560,9 @@ bool Circuit::writeToFile(string filePath) { 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 @@ -484,6 +621,33 @@ bool Circuit::writeToFile(string filePath) { } 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; + file << " getName().getString() << "\" simulModel=\"" << op->getSimulModel().getString() << "\" callOrder=\"" << op->getCallOrder() << "\">" << 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; file.close(); return true; diff --git a/vlsisapd/openChams/Circuit.h b/vlsisapd/openChams/Circuit.h index fd5606b9..64b103bb 100644 --- a/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/openChams/Circuit.h @@ -19,6 +19,8 @@ #include "Instance.h" #include "Net.h" #include "Schematic.h" +#include "Sizing.h" +#include "Operator.h" namespace OpenChams { class Circuit { @@ -31,16 +33,19 @@ class Circuit { inline Netlist* getNetlist(); inline Schematic* getSchematic(); inline void addParameter(Name, double); + inline void addParameter(Name, string); inline Parameters getParameters(); inline void setNetlist(Netlist*); inline void setSchematic(Schematic*); + inline void setSizing(Sizing*); bool writeToFile(string filePath); static Circuit* readFromFile(const string filePath); private: Name readParameter(xmlNode*, double&); + Name readParameterEq(xmlNode*, string&); Name readConnector(xmlNode*); void readCircuitParameters(xmlNode*); void readNetList(xmlNode*); @@ -53,6 +58,11 @@ class Circuit { void readNetConnector(xmlNode*, Net*); void readSchematic(xmlNode*); void readInstanceSchematic(xmlNode*, Schematic*); + void readSizing(xmlNode*); + void readInstanceSizing(xmlNode*, Sizing*); + void readConstraint(xmlNode*, Operator*); + void readEquations(xmlNode*, Sizing*); + void readEquation(xmlNode*, Sizing*); void check_uppercase(string& str, vector& compares, string message); void check_lowercase(string& str, vector& compares, string message); @@ -62,17 +72,20 @@ class Circuit { Parameters _params; Netlist* _netlist; Schematic* _schematic; + Sizing* _sizing; }; -inline Name Circuit::getName() { return _name; } ; +inline Name Circuit::getName() { return _name; }; inline Name Circuit::getTechno() { return _techno; }; inline double Circuit::getValue(Name name) { return _params.getValue(name); }; inline Netlist* Circuit::getNetlist() { return _netlist; }; inline Schematic* Circuit::getSchematic() { return _schematic; }; inline void Circuit::addParameter(Name name, double value) { _params.addParameter(name, value); }; +inline void Circuit::addParameter(Name name, string eqStr) { _params.addParameter(name, eqStr); }; inline Parameters Circuit::getParameters() { return _params; }; inline void Circuit::setNetlist(Netlist* netlist) { _netlist = netlist; }; inline void Circuit::setSchematic(Schematic* schem) { _schematic = schem; }; +inline void Circuit::setSizing(Sizing* sizing) { _sizing = sizing; }; } // namespace IO diff --git a/vlsisapd/openChams/Instance.h b/vlsisapd/openChams/Instance.h index 379ba863..f599f318 100644 --- a/vlsisapd/openChams/Instance.h +++ b/vlsisapd/openChams/Instance.h @@ -28,6 +28,7 @@ class Instance { Instance* getInstance(Name); inline void addParameter(Name, double); + inline void addParameter(Name, std::string); inline Name getName(); inline Name getModel(); inline Name getMosType(); @@ -50,6 +51,7 @@ class Instance { }; inline void Instance::addParameter(Name name, double value) { _params.addParameter(name, value); }; +inline void Instance::addParameter(Name name, std::string eqStr) { _params.addParameter(name, eqStr); }; inline Name Instance::getName() { return _name; }; inline Name Instance::getModel() { return _model; }; inline Name Instance::getMosType() { return _mosType; }; diff --git a/vlsisapd/openChams/Operator.cpp b/vlsisapd/openChams/Operator.cpp new file mode 100644 index 00000000..52f82cda --- /dev/null +++ b/vlsisapd/openChams/Operator.cpp @@ -0,0 +1,49 @@ +/* + * Operator.cpp + * openChams + * + * Created by damien dupuis on 08/02/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +using namespace std; + +#include "Operator.h" +#include "OpenChamsException.h" + +namespace OpenChams { +Operator::Operator(Name operatorName, Name simulModel, unsigned callOrder) + : _name(operatorName) + , _simulModel(simulModel) + , _callOrder(callOrder) {} + +void Operator::addConstraint(Name paramName, Name ref, Name refParam, double factor) { + map::iterator it = _constraints.find(paramName); + if (it != _constraints.end()) { + string error("[ERROR] Cannot set two constraints for the same parameter ("); + error += paramName.getString(); + error += ")."; + throw OpenChamsException(error); + } + _constraints[paramName] = new Operator::Constraint(ref, refParam, factor); +} + +void Operator::addConstraint(Name paramName, Name refEquation, double factor) { + map::iterator it = _constraints.find(paramName); + if (it != _constraints.end()) { + string error("[ERROR] Cannot set two constraints for the same parameter ("); + error += paramName.getString(); + error += ")."; + throw OpenChamsException(error); + } + _constraints[paramName] = new Operator::Constraint(Name(""), refEquation, factor); +} + +Operator::Constraint::Constraint(Name ref, Name refParam, double factor) + : _ref(ref) + , _refParam(refParam) + , _factor(factor) {} +} // namespace + diff --git a/vlsisapd/openChams/Operator.h b/vlsisapd/openChams/Operator.h new file mode 100644 index 00000000..b812f3fc --- /dev/null +++ b/vlsisapd/openChams/Operator.h @@ -0,0 +1,65 @@ +/* + * Operator.h + * openChams + * + * Created by damien dupuis on 08/02/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_OPERATOR_H__ +#define __OPENCHAMS_OPERATOR_H__ + +#include + +#include "Name.h" + +namespace OpenChams { +class Operator { + public: + class Constraint { + public: + Constraint(Name ref, Name refParam, double factor); + + inline Name getRef(); + inline Name getRefParam(); + inline double getFactor(); + + private: + Name _ref; + Name _refParam; + double _factor; + }; + + public: + Operator(Name operatorName, Name simulModel, unsigned callOrder); + + void addConstraint(Name paramName, Name ref, Name refParam, double factor = 1.0); + void addConstraint(Name paramName, Name refEquation, double factor = 1.0); + + inline Name getName(); + inline Name getSimulModel(); + inline unsigned getCallOrder(); + inline bool hasNoConstraints(); + inline const std::map& getConstraints(); + + private: + Name _name; + Name _simulModel; + unsigned _callOrder; + std::map _constraints; +}; + + inline Name Operator::getName() { return _name; }; + inline Name Operator::getSimulModel() { return _simulModel; }; + inline unsigned Operator::getCallOrder() { return _callOrder; }; + inline bool Operator::hasNoConstraints() { return (_constraints.size() == 0) ? true : false; }; + inline const std::map& Operator::getConstraints() { return _constraints; }; + + inline Name Operator::Constraint::getRef() { return _ref; }; + inline Name Operator::Constraint::getRefParam() { return _refParam; }; + inline double Operator::Constraint::getFactor() { return _factor; }; + +} // namespace +#endif + diff --git a/vlsisapd/openChams/Parameters.cpp b/vlsisapd/openChams/Parameters.cpp index 7f90a81b..ad96b6e6 100644 --- a/vlsisapd/openChams/Parameters.cpp +++ b/vlsisapd/openChams/Parameters.cpp @@ -8,6 +8,7 @@ */ #include +#include using namespace std; #include "Parameters.h" @@ -27,14 +28,26 @@ double Parameters::getValue(Name name) { void Parameters::addParameter(Name name, double value) { map::iterator it = _params.find(name); - if ( it != _params.end() ) { + map::iterator it2 = _paramsEq.find(name); + if ( it != _params.end() || it2 != _paramsEq.end() ) { string error("[ERROR] Cannot addParameter "); error += name.getString(); error += " because it already exists !"; throw OpenChamsException(error); - //return; } _params[name] = value; } + +void Parameters::addParameter(Name name, string eqStr) { + map::iterator it = _params.find(name); + map::iterator it2 = _paramsEq.find(name); + if ( it != _params.end() || it2 != _paramsEq.end() ) { + string error("[ERROR] Cannot addParameter "); + error += name.getString(); + error += " because it already exists !"; + throw OpenChamsException(error); + } + _paramsEq[name] = eqStr; +} } // namespace diff --git a/vlsisapd/openChams/Parameters.h b/vlsisapd/openChams/Parameters.h index d6d2a698..a38e02e3 100644 --- a/vlsisapd/openChams/Parameters.h +++ b/vlsisapd/openChams/Parameters.h @@ -19,23 +19,24 @@ class Parameters { public: Parameters() {}; - double getValue(Name); - void addParameter(Name, double); + double getValue(Name); + std::string getEqValue(Name); + void addParameter(Name, double); + void addParameter(Name, std::string); // pour parcourir la map : inline bool isEmpty(); - //inline map::iterator getFirstIt(); - //inline map::iterator getLastIt(); - inline const std::map& getValues(); + inline const std::map& getValues(); + inline const std::map& getEqValues(); private: - std::map _params; + std::map _params; + std::map _paramsEq; }; -inline bool Parameters::isEmpty() { return (_params.size() == 0)? true : false; } -//inline map::iterator Parameters::getFirstIt() { return _params.begin(); } -//inline map::iterator Parameters::getLastIt() { return _params.end(); } -inline const std::map& Parameters::getValues() { return _params; }; +inline bool Parameters::isEmpty() { return ((_params.size() == 0)&&(_paramsEq.size() == 0))? true : false; } +inline const std::map& Parameters::getValues() { return _params; }; +inline const std::map& Parameters::getEqValues() { return _paramsEq; }; } // namespace #endif diff --git a/vlsisapd/openChams/Sizing.cpp b/vlsisapd/openChams/Sizing.cpp new file mode 100644 index 00000000..31070d9e --- /dev/null +++ b/vlsisapd/openChams/Sizing.cpp @@ -0,0 +1,45 @@ +/* + * Sizing.cpp + * openChams + * + * Created by damien dupuis on 08/02/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +using namespace std; + +#include "Sizing.h" +#include "Circuit.h" +#include "Operator.h" +#include "OpenChamsException.h" + +namespace OpenChams { +Sizing::Sizing(Circuit* circuit): _circuit(circuit) {} + +Operator* Sizing::addOperator(Name instanceName, Name operatorName, Name simulModel, unsigned callOrder) { + map::iterator it = _operators.find(instanceName); + if (it != _operators.end()) { + string error("[ERROR] Cannot set same instance twice in 'sizing' ("); + error += instanceName.getString(); + error += ")."; + throw OpenChamsException(error); + } + Operator* op = new Operator(operatorName, simulModel, callOrder); + _operators[instanceName] = op; + return op; +} + +void Sizing::addEquation(Name equationName, string 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(); + error += ")."; + throw OpenChamsException(error); + } + _equations[equationName] = equation; +} + +} // namespace \ No newline at end of file diff --git a/vlsisapd/openChams/Sizing.h b/vlsisapd/openChams/Sizing.h new file mode 100644 index 00000000..47d1f7b7 --- /dev/null +++ b/vlsisapd/openChams/Sizing.h @@ -0,0 +1,44 @@ +/* + * Sizing.h + * openChams + * + * Created by damien dupuis on 08/02/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_SIZING_H__ +#define __OPENCHAMS_SIZING_H__ + +#include + +#include "Name.h" + +namespace OpenChams { + class Circuit; + class Operator; + class Sizing { + public: + Sizing(Circuit*); + + Operator* addOperator(Name instanceName, Name operatorName, Name simulModel, unsigned callOrder); + 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) + }; + + 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 +