Now can parse / drive the sizing procedure.

This commit is contained in:
Damien Dupuis 2010-02-09 12:16:04 +00:00
parent 4d27f3075b
commit c34902020c
10 changed files with 413 additions and 17 deletions

View File

@ -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})

View File

@ -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<string>& 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<unsigned>(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<double>(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<double>(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<Name, double>::const_iterator it = _params.getValues().begin() ; it != _params.getValues().end() ; ++it) {
file << " <parameter name=\"" << (*it).first.getString() << "\" value=\"" << (*it).second << "\"/>" << endl;
}
for (map<Name, string>::const_iterator it = _params.getEqValues().begin() ; it != _params.getEqValues().end() ; ++it) {
file << " <parameterEq name=\"" << (*it).first.getString() << "\" equation=\"" << (*it).second << "\"/>" << endl;
}
file << " </parameters>" << endl;
}
file << " <netlist>" << endl
@ -484,6 +621,33 @@ bool Circuit::writeToFile(string filePath) {
}
file << " </schematic>" << endl;
}
if (_sizing && !_sizing->hasNoOperators()) {
file << " <sizing>" << endl;
for (map<Name, Operator*>::const_iterator it = _sizing->getOperators().begin() ; it != _sizing->getOperators().end() ; ++it) {
Operator* op = (*it).second;
file << " <instance name=\"" << ((*it).first).getString() << "\" operator=\"" << op->getName().getString() << "\" simulModel=\"" << op->getSimulModel().getString() << "\" callOrder=\"" << op->getCallOrder() << "\">" << endl;
if (!op->hasNoConstraints()) {
for (map<Name, Operator::Constraint*>::const_iterator cit = op->getConstraints().begin() ; cit != op->getConstraints().end() ; ++cit) {
Operator::Constraint* cn = (*cit).second;
Name ref = cn->getRef();
if (ref == Name("")) {
file << " <constraint param=\"" << ((*cit).first).getString() << "\" refEquation=\"" << cn->getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl;
} else {
file << " <constraint param=\"" << ((*cit).first).getString() << "\" ref=\"" << cn->getRef().getString() << "\" refParam=\"" << cn->getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl;
}
}
}
file << " </instance>" << endl;
}
if (!_sizing->hasNoEquations()) {
file << " <equations>" << endl;
for (map<Name, string>::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) {
file << " <eq name=\"" << ((*it).first).getString() << "\" equation=\"" << (*it).second << "\"/>" << endl;
}
file << " </equations>" << endl;
}
file << " </sizing>" << endl;
}
file << "</circuit>" << endl;
file.close();
return true;

View File

@ -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<string>& compares, string message);
void check_lowercase(string& str, vector<string>& 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

View File

@ -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; };

View File

@ -0,0 +1,49 @@
/*
* Operator.cpp
* openChams
*
* Created by damien dupuis on 08/02/10.
* Copyright 2010 UPMC / LIP6. All rights reserved.
*
*/
#include <string>
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<Name, Constraint*>::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<Name, Constraint*>::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

View File

@ -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 <map>
#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<Name, Constraint*>& getConstraints();
private:
Name _name;
Name _simulModel;
unsigned _callOrder;
std::map<Name, Constraint*> _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<Name, Operator::Constraint*>& 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

View File

@ -8,6 +8,7 @@
*/
#include <iostream>
#include <string>
using namespace std;
#include "Parameters.h"
@ -27,14 +28,26 @@ double Parameters::getValue(Name name) {
void Parameters::addParameter(Name name, double value) {
map<Name, double>::iterator it = _params.find(name);
if ( it != _params.end() ) {
map<Name, string>::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<Name, double>::iterator it = _params.find(name);
map<Name, string>::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

View File

@ -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<Name, double>::iterator getFirstIt();
//inline map<Name, double>::iterator getLastIt();
inline const std::map<Name, double>& getValues();
inline const std::map<Name, double>& getValues();
inline const std::map<Name, std::string>& getEqValues();
private:
std::map<Name, double> _params;
std::map<Name, double> _params;
std::map<Name, std::string> _paramsEq;
};
inline bool Parameters::isEmpty() { return (_params.size() == 0)? true : false; }
//inline map<Name, double>::iterator Parameters::getFirstIt() { return _params.begin(); }
//inline map<Name, double>::iterator Parameters::getLastIt() { return _params.end(); }
inline const std::map<Name, double>& Parameters::getValues() { return _params; };
inline bool Parameters::isEmpty() { return ((_params.size() == 0)&&(_paramsEq.size() == 0))? true : false; }
inline const std::map<Name, double>& Parameters::getValues() { return _params; };
inline const std::map<Name, string>& Parameters::getEqValues() { return _paramsEq; };
} // namespace
#endif

View File

@ -0,0 +1,45 @@
/*
* Sizing.cpp
* openChams
*
* Created by damien dupuis on 08/02/10.
* Copyright 2010 UPMC / LIP6. All rights reserved.
*
*/
#include <string>
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<Name, Operator*>::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<Name, string>::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

View File

@ -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 <map>
#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<Name, Operator*>& getOperators();
inline const std::map<Name, std::string>& getEquations();
private:
Circuit* _circuit;
std::map<Name, Operator*> _operators; //instanceName <-> operator
std::map<Name, std::string> _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<Name, Operator*>& Sizing::getOperators() { return _operators; };
inline const std::map<Name, std::string>& Sizing::getEquations() { return _equations; };
} // namespace
#endif