New standalone openChams parser/driver.
Right now, only <netlist> section is supported.
This commit is contained in:
parent
37b71a532f
commit
d2fa201e09
|
@ -4,5 +4,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0)
|
|||
|
||||
SET(CMAKE_MODULE_PATH "${IO_SOURCE_DIR}/cmake_modules/")
|
||||
|
||||
FIND_PACKAGE(LibXml2 REQUIRED)
|
||||
|
||||
ADD_SUBDIRECTORY(agds)
|
||||
ADD_SUBDIRECTORY(openChams)
|
||||
ADD_SUBDIRECTORY(cmake_modules)
|
||||
|
|
|
@ -7,30 +7,56 @@
|
|||
|
||||
SET(IO_DIR_SEARCH $ENV{IO_TOP})
|
||||
|
||||
FIND_PATH(IO_INCLUDE_DIR
|
||||
SET(IO_FOUND FALSE)
|
||||
# AGDS
|
||||
FIND_PATH(AGDS_INCLUDE_DIR
|
||||
NAMES io/agds/GdsLibrary.h
|
||||
PATHS ${IO_DIR_SEARCH}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(IO_AGDS_LIBRARY
|
||||
FIND_LIBRARY(AGDS_LIBRARY
|
||||
NAMES agds
|
||||
PATHS ${IO_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
IF(AGDS_INCLUDE_DIR AND AGDS_LIBRARY)
|
||||
SET(AGDS_FOUND TRUE)
|
||||
#SET(IO_FOUND TRUE)
|
||||
# SET(IO_LIBRARIES ${AGDS_LIBRARY})
|
||||
ELSE(AGDS_INCLUDE_DIR AND AGDS_LIBRARY)
|
||||
SET(AGDS_FOUND FALSE)
|
||||
# SET(IO_LIBRARIES)
|
||||
ENDIF(AGDS_INCLUDE_DIR AND AGDS_LIBRARY)
|
||||
|
||||
# OPENCHAMS
|
||||
FIND_PATH(OPENCHAMS_INCLUDE_DIR
|
||||
NAMES io/openChams/Circuit.h
|
||||
PATHS ${IO_DIR_SEARCH}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
FIND_LIBRARY(OPENCHAMS_LIBRARY
|
||||
NAMES openChams
|
||||
PATHS ${IO_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib
|
||||
)
|
||||
IF(OPENCHAMS_INCLUDE_DIR AND OPENCHAMS_LIBRARY)
|
||||
SET(OPENCHAMS_FOUND TRUE)
|
||||
#SET(IO_FOUND TRUE)
|
||||
# SET(IO_LIBRARIES ${OPENCHAMS_LIBRARY})
|
||||
ELSE(OPENCHAMS_INCLUDE_DIR AND OPENCHAMS_LIBRARY)
|
||||
SET(OPENCHAMS_FOUND FALSE)
|
||||
# SET(IO_LIBRARIES)
|
||||
ENDIF(OPENCHAMS_INCLUDE_DIR AND OPENCHAMS_LIBRARY)
|
||||
|
||||
IF(IO_INCLUDE_DIR AND IO_AGDS_LIBRARY)
|
||||
SET(IO_FOUND TRUE)
|
||||
SET(IO_LIBRARIES ${IO_AGDS_LIBRARY})
|
||||
ELSE(IO_INCLUDE_DIR AND IO_AGDS_LIBRARY)
|
||||
SET(IO_FOUND FALSE)
|
||||
SET(IO_LIBRARIES)
|
||||
ENDIF(IO_INCLUDE_DIR AND IO_AGDS_LIBRARY)
|
||||
IF(AGDS_FOUND AND OPENCHAMS_FOUND)
|
||||
SET(IO_FOUND TRUE)
|
||||
ELSE(AGDS_FOUND AND OPENCHAMS_FOUND)
|
||||
SET(IO_FOUND FALSE)
|
||||
ENDIF(AGDS_FOUND AND OPENCHAMS_FOUND)
|
||||
|
||||
IF (NOT IO_FOUND)
|
||||
SET(IO_MESSAGE
|
||||
"IO library was not found. Make sure IO_TOP env variable is set.")
|
||||
"IO libraries were not found. Make sure IO_TOP env variable is set.")
|
||||
IF (NOT IO_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "${IO_MESSAGE}")
|
||||
ELSE(NOT IO_FIND_QUIETLY)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
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 )
|
||||
|
||||
ADD_LIBRARY(openChams SHARED ${cpps})
|
||||
|
||||
TARGET_LINK_LIBRARIES(openChams ${LIBXML2_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS openChams DESTINATION /lib)
|
||||
|
||||
INSTALL(FILES ${includes} DESTINATION /include/io/openChams)
|
|
@ -0,0 +1,360 @@
|
|||
/*
|
||||
* Circuit.cpp
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 18/12/09.
|
||||
* Copyright 2009 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
#include "Circuit.h"
|
||||
|
||||
namespace {
|
||||
template<class T> T getValue(xmlChar* str) {
|
||||
std::istringstream iss;
|
||||
iss.str((const char*) str);
|
||||
T res;
|
||||
iss >> res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
namespace OpenChams {
|
||||
|
||||
static bool readCircuitParametersDone = false;
|
||||
static bool readNetListDone = false;
|
||||
static bool readInstancesDone = false;
|
||||
static bool readNetsDone = false;
|
||||
|
||||
Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno) {}
|
||||
|
||||
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<double>(valueC);
|
||||
return name;
|
||||
} else {
|
||||
cerr << "[ERROR] 'parameter' node must have 'name' and 'value' properties." << endl;
|
||||
return Name("");
|
||||
}
|
||||
}
|
||||
|
||||
Name Circuit::readConnector(xmlNode* node) {
|
||||
xmlChar* connectorNameC = xmlGetProp(node, (xmlChar*)"name");
|
||||
if (connectorNameC) {
|
||||
Name name((const char*)connectorNameC);
|
||||
return name;
|
||||
} else {
|
||||
cerr << "[ERROR] 'connector' node must have 'name' property." << endl;
|
||||
return Name("");
|
||||
}
|
||||
}
|
||||
|
||||
void Circuit::readCircuitParameters(xmlNode* node) {
|
||||
if (readCircuitParametersDone) {
|
||||
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 {
|
||||
cerr << "[WARNING] Only 'parameter' nodes are authorized under 'parameters' node." << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
readCircuitParametersDone = true;
|
||||
}
|
||||
|
||||
void Circuit::readNetList(xmlNode* node) {
|
||||
if (readNetListDone) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
readNetListDone = true;
|
||||
_netlist = netlist;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
xmlNode* child = node->children;
|
||||
for (xmlNode* node = child; node; node = node->next) {
|
||||
if (node->type == XML_ELEMENT_NODE) {
|
||||
if (xmlStrEqual(node->name, (xmlChar*)"instance")) {
|
||||
Instance* inst =readInstance(node, netlist);
|
||||
netlist->addInstance(inst);
|
||||
} else {
|
||||
cerr << "[WARNING] Only 'instance' nodes are allowed in 'instances', others will be ignored." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
readInstancesDone = true;
|
||||
}
|
||||
|
||||
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");
|
||||
Instance* inst = NULL;
|
||||
if (iNameC && iModelC && iMOSC) {
|
||||
Name instanceName((const char*)iNameC);
|
||||
Name modelName((const char*)iModelC);
|
||||
Name mosName((const char*)iMOSC);
|
||||
inst = new Instance(instanceName, modelName, mosName, netlist);
|
||||
} else {
|
||||
cerr << "[ERROR] 'instance' node must have 'name', 'model' and 'mos' properties." << endl;
|
||||
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 {
|
||||
cerr << "[WARNING] Only 'conectors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
readNetsDone = true;
|
||||
}
|
||||
|
||||
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);
|
||||
Name typeName((const char*)nTypeC);
|
||||
string externStr((const char*)nExternC);
|
||||
bool isExternal = (externStr == "True") ? true : false;
|
||||
net = new Net(netName, typeName, isExternal, netlist);
|
||||
netlist->addNet(net);
|
||||
} else {
|
||||
cerr << "[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties." << endl;
|
||||
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 'conector' nodes are allowed in 'net', others will be ignored." << endl;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 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) {
|
||||
cerr << "[ERROR] no instance named \"" << iName.getString() << "\" in connector of net \"" << net->getName().getString() << "\"." << endl;
|
||||
return;
|
||||
}
|
||||
inst->connect(cName, net->getName());
|
||||
net->connectTo(iName, cName);
|
||||
} else {
|
||||
cerr << "[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
Circuit* Circuit::readFromFile(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;
|
||||
}
|
||||
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");
|
||||
|
||||
if (circuitNameC && technoNameC) {
|
||||
Name circuitName ((const char*)circuitNameC);
|
||||
Name technoName ((const char*)technoNameC);
|
||||
cir = new Circuit(circuitName, technoName);
|
||||
} else {
|
||||
cerr << "[ERROR] 'circuit' node must have 'name' and 'techno' properties." << endl;
|
||||
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*)"parameters")) {
|
||||
cir->readCircuitParameters(node);
|
||||
}
|
||||
if (xmlStrEqual(node->name, (xmlChar*)"netlist")) {
|
||||
cir->readNetList(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cir;
|
||||
}
|
||||
|
||||
bool Circuit::writeToFile(string filePath) {
|
||||
ofstream file;
|
||||
file.open(filePath.c_str());
|
||||
// checks before do anything
|
||||
if (!_netlist) {
|
||||
cerr << "[ERROR] Cannot writeToFile since no netlist is defined !" << endl;
|
||||
return false;
|
||||
}
|
||||
if (_netlist->hasNoInstances()) {
|
||||
cerr << "[ERROR] Cannot writeToFile since no instance is defined in netlist !" << endl;
|
||||
return false;
|
||||
}
|
||||
if (_netlist->hasNoNets()) {
|
||||
cerr << "[ERROR] Cannot writeToFile since no net is defined in netlist !" << endl;
|
||||
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) {
|
||||
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) {
|
||||
Instance* inst = (*it);
|
||||
if (inst->hasNoConnectors()) {
|
||||
cerr << "[ERROR] Cannot writeToFile since instance (" << inst->getName().getString() << ") has no connectors !" << endl;
|
||||
return false;
|
||||
}
|
||||
file << " <instance name=\"" << inst->getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\">" << endl;
|
||||
file << " <connectors>" << endl;
|
||||
for (map<Name, Net*>::iterator it = inst->getFirstConnectorIt() ; it != inst->getLastConnectorIt() ; ++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) {
|
||||
file << " <parameter name=\"" << (*it).first.getString() << "\" value=\"" << (*it).second << "\"/>" << endl;
|
||||
}
|
||||
file << " </parameters>" << endl;
|
||||
}
|
||||
file << " </instance>" << endl;
|
||||
}
|
||||
file << " </instances>" << endl
|
||||
<< " <nets>" << endl;
|
||||
for (vector<Net*>::iterator it = _netlist->getFirstNetIt() ; it != _netlist->getLastNetIt() ; ++it) {
|
||||
Net* net = (*it);
|
||||
if (net->hasNoConnectors()) {
|
||||
cerr << "[ERROR] Cannot writeToFile since net (" << net->getName().getString() << ") has no connectors !" << endl;
|
||||
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) {
|
||||
file << " <connector instance=\"" << (*it).first.getString() << "\" name=\"" << (*it).second.getString() << "\"/>" << endl;
|
||||
}
|
||||
file << " </net>" << endl;
|
||||
}
|
||||
file << " </nets>" << endl;
|
||||
file << " </netlist>" << endl;
|
||||
file << "</circuit>" << endl;
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Circuit.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 18/12/09.
|
||||
* Copyright 2009 UPMC / LIP6 All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENCHAMS_CIRCUIT_H__
|
||||
#define __OPENCHAMS_CIRCUIT_H__
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
#include "Name.h"
|
||||
#include "Parameters.h"
|
||||
#include "Netlist.h"
|
||||
#include "Instance.h"
|
||||
#include "Net.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);
|
||||
|
||||
bool writeToFile(string filePath);
|
||||
static Circuit* readFromFile(string filePath);
|
||||
|
||||
private:
|
||||
Name readParameter(xmlNode*, double&);
|
||||
Name readConnector(xmlNode*);
|
||||
void readCircuitParameters(xmlNode*);
|
||||
void readNetList(xmlNode*);
|
||||
void readInstances(xmlNode*, Netlist*);
|
||||
Instance* readInstance (xmlNode*, Netlist*);
|
||||
void readInstanceParameters(xmlNode*, Instance*);
|
||||
void readInstanceConnectors(xmlNode*, Instance*);
|
||||
void readNets(xmlNode*, Netlist*);
|
||||
Net* readNet (xmlNode*, Netlist*);
|
||||
void readNetConnector(xmlNode*, Net*);
|
||||
|
||||
|
||||
Name _name;
|
||||
Name _techno;
|
||||
Parameters _params;
|
||||
Netlist* _netlist;
|
||||
};
|
||||
|
||||
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); }
|
||||
|
||||
|
||||
} // namespace IO
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Instance.cpp
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 12/01/10.
|
||||
* Copyright 2010 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "Instance.h"
|
||||
#include "Netlist.h"
|
||||
#include "Net.h"
|
||||
|
||||
namespace OpenChams {
|
||||
Instance::Instance(Name name, Name model, Name mosType, Netlist* netlist)
|
||||
: _name(name)
|
||||
, _model(model)
|
||||
, _mosType(mosType)
|
||||
, _netlist(netlist) {}
|
||||
|
||||
void Instance::addConnector(Name name) {
|
||||
// si name n'est pas déjà présent dans la map on ajoute name, NULL (pas de net)
|
||||
map<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;
|
||||
}
|
||||
|
||||
void Instance::connect(Name connectorName, Name netName) {
|
||||
// si connectorName n'est pas déjà présent dans la map :
|
||||
// on cherche le net associé a netName dans la netlist (getNet(Name))
|
||||
// on ajoute cName, net a la map
|
||||
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;
|
||||
else
|
||||
_netMap[connectorName] = net;
|
||||
}
|
||||
else
|
||||
cerr << "[ERROR] While connecting instance : connector (" << connectorName.getString() << ") does not exist." << endl;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Instance.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 12/01/10.
|
||||
* Copyright 2010 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENCHAMS_INSTANCE_H__
|
||||
#define __OPENCHAMS_INSTANCE_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
#include "Name.h"
|
||||
#include "Parameters.h"
|
||||
|
||||
namespace OpenChams {
|
||||
class Netlist;
|
||||
class Net;
|
||||
class Instance {
|
||||
public:
|
||||
Instance(Name name, Name model, Name mosType, Netlist*);
|
||||
|
||||
void addConnector(Name);
|
||||
void connect(Name connectorName, Name netName);
|
||||
|
||||
Instance* getInstance(Name);
|
||||
|
||||
inline void addParameter(Name, double);
|
||||
inline Name getName();
|
||||
inline Name getModel();
|
||||
inline Name getMosType();
|
||||
inline Parameters getParameters();
|
||||
// pour parcourir les connecteurs
|
||||
inline bool hasNoConnectors();
|
||||
inline map<Name, Net*>::iterator getFirstConnectorIt();
|
||||
inline map<Name, Net*>::iterator getLastConnectorIt();
|
||||
|
||||
private:
|
||||
Name _name;
|
||||
Name _model;
|
||||
Name _mosType;
|
||||
Netlist* _netlist;
|
||||
Parameters _params;
|
||||
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 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(); };
|
||||
|
||||
} // namespace
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Name.cpp
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 18/12/09.
|
||||
* Copyright 2009 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Name.h"
|
||||
|
||||
namespace OpenChams {
|
||||
unsigned long Name::_globalId = 0;
|
||||
map<string, unsigned long> Name::_dict;
|
||||
|
||||
Name::Name(string str) {
|
||||
map<string, unsigned long>::iterator it = _dict.find(str);
|
||||
if (it != _dict.end()) {
|
||||
_id = (*it).second;
|
||||
_str = &((*it).first);
|
||||
} else {
|
||||
_id = _globalId++;
|
||||
it = _dict.insert(_dict.begin(), make_pair(str, _id));
|
||||
_str = &((*it).first);
|
||||
}
|
||||
}
|
||||
|
||||
Name::Name(const char* c) {
|
||||
string str(c);
|
||||
map<string, unsigned long>::iterator it = _dict.find(str);
|
||||
if (it != _dict.end()) {
|
||||
_id = (*it).second;
|
||||
_str = &((*it).first);
|
||||
} else {
|
||||
_id = _globalId++;
|
||||
it = _dict.insert(_dict.begin(), make_pair(str, _id));
|
||||
_str = &((*it).first);
|
||||
}
|
||||
}
|
||||
|
||||
bool Name::operator==(const Name& n) {
|
||||
return (_id == n._id);
|
||||
}
|
||||
|
||||
bool Name::operator==(const string& str) {
|
||||
Name n(str);
|
||||
return (_id == n._id);
|
||||
}
|
||||
bool Name::operator<(const Name n) const {
|
||||
return (_id < n._id);
|
||||
}
|
||||
} // namespace
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Name.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 18/12/09.
|
||||
* Copyright 2009 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENCHAMS_NAME_H__
|
||||
#define __OPENCHAMS_NAME_H__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
namespace OpenChams {
|
||||
class Name {
|
||||
public:
|
||||
Name(string);
|
||||
Name(const char*);
|
||||
|
||||
bool operator==(const Name&);
|
||||
bool operator==(const string&);
|
||||
bool operator<(const Name) const;
|
||||
|
||||
inline const string& getString() const;
|
||||
|
||||
private:
|
||||
unsigned long _id;
|
||||
const string *_str;
|
||||
|
||||
static map<string, unsigned long> _dict;
|
||||
static unsigned long _globalId;
|
||||
};
|
||||
|
||||
const string& Name::getString() const{
|
||||
return *_str;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Net.cpp
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 12/01/10.
|
||||
* Copyright 2010 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Net.h"
|
||||
#include "Netlist.h"
|
||||
|
||||
namespace OpenChams {
|
||||
Net::Net(Name netName, Name typeName, bool isExternal, Netlist* netlist)
|
||||
: _name(netName)
|
||||
, _typeName(typeName)
|
||||
, _isExternal(isExternal)
|
||||
, _netlist(netlist) {}
|
||||
|
||||
void Net::connectTo(Name instanceName, Name connectorName) {
|
||||
_connections.push_back(pair<Name, Name>(instanceName, connectorName));
|
||||
}
|
||||
} // namespace
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Net.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 12/01/10.
|
||||
* Copyright 2010 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENCHAMS_NET_H__
|
||||
#define __OPENCHAMS_NET_H__
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include "Name.h"
|
||||
#include "Instance.h"
|
||||
//#include "Net.h"
|
||||
|
||||
namespace OpenChams {
|
||||
class Netlist;
|
||||
class Net {
|
||||
public:
|
||||
Net(Name netName, Name typeName, bool, Netlist*);
|
||||
|
||||
void connectTo(Name instanceName, Name connectorName);
|
||||
|
||||
inline Name getName();
|
||||
inline Name getType();
|
||||
inline bool isExternal();
|
||||
inline Netlist* getNetlist();
|
||||
inline bool hasNoConnectors();
|
||||
inline vector<pair<Name, Name> >::iterator getFirstConnectionIt();
|
||||
inline vector<pair<Name, Name> >::iterator getLastConnectionIt();
|
||||
|
||||
private:
|
||||
Name _name;
|
||||
Name _typeName;
|
||||
bool _isExternal;
|
||||
Netlist* _netlist;
|
||||
vector< pair<Name, Name> > _connections; // <instanceName, connectorName>
|
||||
};
|
||||
|
||||
inline Name Net::getName() { return _name; };
|
||||
inline Name Net::getType() { return _typeName; };
|
||||
inline bool Net::isExternal() { return _isExternal; };
|
||||
inline Netlist* Net::getNetlist() { return _netlist; };
|
||||
inline bool Net::hasNoConnectors() { return (_connections.size() == 0)? true : false; };
|
||||
inline vector<pair<Name, Name> >::iterator Net::getFirstConnectionIt() { return _connections.begin();};
|
||||
inline vector<pair<Name, Name> >::iterator Net::getLastConnectionIt() { return _connections.end();};
|
||||
|
||||
} // namespace
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* NetList.cpp
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 12/01/10.
|
||||
* Copyright 2010 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
#include "NetList.h"
|
||||
#include "Circuit.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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Instance* Netlist::getInstance(Name instanceName) {
|
||||
for (size_t i = 0 ; i < _instances.size() ; ++i) {
|
||||
if (_instances[i]->getName() == instanceName) {
|
||||
return _instances[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Net* Netlist::getNet(Name netName) {
|
||||
for (size_t i = 0; i < _nets.size(); ++i) {
|
||||
if (_nets[i]->getName() == netName) {
|
||||
return _nets[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
} // namespace
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* NetList.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 12/01/10.
|
||||
* Copyright 2010 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENCHAMS_NETLIST_H__
|
||||
#define __OPENCHAMS_NETLIST_H__
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include "Name.h"
|
||||
#include "Instance.h"
|
||||
#include "Net.h"
|
||||
|
||||
namespace OpenChams {
|
||||
class Circuit;
|
||||
class Netlist {
|
||||
public:
|
||||
Netlist(Circuit*);
|
||||
|
||||
void addInstance(Instance*);
|
||||
void addNet(Net*);
|
||||
|
||||
Instance* getInstance(Name);
|
||||
Net* getNet(Name);
|
||||
|
||||
//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();
|
||||
|
||||
private:
|
||||
Circuit* _circuit;
|
||||
vector<Instance*> _instances;
|
||||
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(); }
|
||||
|
||||
} // namespace
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Parameters.cpp
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 18/12/09.
|
||||
* Copyright 2009 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#include "Parameters.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;
|
||||
}
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
_params[name] = value;
|
||||
}
|
||||
} // namespace
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Parameters.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 18/12/09.
|
||||
* Copyright 2009 UPMC / LIP6. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OPENCHAMS_PARAMETERS_H__
|
||||
#define __OPENCHAMS_PARAMETERS_H__
|
||||
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
#include "Name.h"
|
||||
|
||||
namespace OpenChams {
|
||||
class Parameters {
|
||||
public:
|
||||
Parameters() {};
|
||||
|
||||
double getValue(Name);
|
||||
void addParameter(Name, double);
|
||||
|
||||
// pour parcourir la map :
|
||||
inline bool isEmpty();
|
||||
inline map<Name, double>::iterator getFirstIt();
|
||||
inline map<Name, double>::iterator getLastIt();
|
||||
|
||||
private:
|
||||
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(); }
|
||||
|
||||
} // namespace
|
||||
#endif
|
Loading…
Reference in New Issue