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