in order to compile (in fact link) on mac osx 10.6 I re-added the TARGET_LINK_LIBRARIES (as cmake documentation specifies it)

JP need to check if it the 'static variable bug' still occurs

    Note that in openChams I added SimulModel support, it has not yet been tested, and driver does not support it.
This commit is contained in:
Damien Dupuis 2010-07-07 13:48:28 +00:00
parent b0b3d50c3e
commit 747022ab90
19 changed files with 712 additions and 69 deletions

View File

@ -1,16 +1,17 @@
INCLUDE_DIRECTORIES(${VLSISAPD_SOURCE_DIR}/src/openChams/src ${LIBXML2_INCLUDE_DIR})
INCLUDE_DIRECTORIES(${VLSISAPD_SOURCE_DIR}/src/openChams/src ${LIBXML2_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH})
SET ( includes vlsisapd/openChams/Circuit.h
vlsisapd/openChams/Netlist.h
vlsisapd/openChams/Instance.h
vlsisapd/openChams/Net.h
vlsisapd/openChams/Name.h
vlsisapd/openChams/Operator.h
vlsisapd/openChams/Parameters.h
vlsisapd/openChams/Schematic.h
vlsisapd/openChams/Sizing.h
vlsisapd/openChams/Transistor.h
vlsisapd/openChams/OpenChamsException.h
SET ( hpps vlsisapd/openChams/Circuit.h
vlsisapd/openChams/Netlist.h
vlsisapd/openChams/Instance.h
vlsisapd/openChams/Net.h
vlsisapd/openChams/Name.h
vlsisapd/openChams/Operator.h
vlsisapd/openChams/Parameters.h
vlsisapd/openChams/Schematic.h
vlsisapd/openChams/SimulModel.h
vlsisapd/openChams/Sizing.h
vlsisapd/openChams/Transistor.h
vlsisapd/openChams/OpenChamsException.h
)
SET ( cpps Circuit.cpp
Netlist.cpp
@ -20,12 +21,24 @@ SET ( cpps Circuit.cpp
Operator.cpp
Parameters.cpp
Schematic.cpp
SimulModel.cpp
Sizing.cpp
Transistor.cpp
)
SET ( pycpps PyOpenChams.cpp ${cpps})
ADD_LIBRARY(openChams ${cpps})
TARGET_LINK_LIBRARIES(openChams ${LIBXML2_LIBRARIES})
INSTALL(TARGETS openChams DESTINATION lib${LIB_SUFFIX} )
INSTALL(FILES ${includes} DESTINATION include/vlsisapd/openChams)
IF(Boost_FOUND)
ADD_LIBRARY(pyOPENCHAMS MODULE ${pycpps})
SET_TARGET_PROPERTIES(pyOPENCHAMS PROPERTIES
COMPILE_FLAGS "${COMPILE_FLAGS} -D__PYTHON_MODULE__=1"
PREFIX ""
)
TARGET_LINK_LIBRARIES(pyOPENCHAMS openChams ${LIBXML2_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
INSTALL(TARGETS pyOPENCHAMS DESTINATION ${PYTHON_SITE_PACKAGES})
ENDIF(Boost_FOUND)
INSTALL(FILES ${hpps} DESTINATION include/vlsisapd/openChams)

View File

@ -19,6 +19,7 @@ using namespace std;
#include "vlsisapd/openChams/Instance.h"
#include "vlsisapd/openChams/Net.h"
#include "vlsisapd/openChams/Schematic.h"
#include "vlsisapd/openChams/SimulModel.h"
#include "vlsisapd/openChams/Sizing.h"
#include "vlsisapd/openChams/Transistor.h"
#include "vlsisapd/openChams/Operator.h"
@ -37,14 +38,16 @@ namespace {
namespace OpenChams {
static bool readCircuitParametersDone = false;
static bool readNetListDone = false;
static bool readInstancesDone = false;
static bool readNetsDone = false;
static bool readSchematicDone = false;
static bool readSizingDone = false;
static bool readSimulModelsDone = false;
static bool readNetListDone = false;
static bool readInstancesDone = false;
static bool readNetsDone = false;
static bool readSchematicDone = false;
static bool readSizingDone = false;
Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL) {
readCircuitParametersDone = false;
readSimulModelsDone = false;
readNetListDone = false;
readInstancesDone = false;
readNetsDone = false;
@ -53,8 +56,8 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis
}
// COMPARISON FUNCTION //
bool ConnectionsSort(const pair<Name, Name>& p1, const pair<Name, Name>& p2) {
return p1.first < p2.first;
bool ConnectionsSort(const Net::Connection* c1, const Net::Connection* c2) {
return c1->getInstanceName() < c2->getInstanceName();
}
bool InstanceNameSort(const Instance* i1, const Instance* i2) {
@ -92,6 +95,14 @@ void Circuit::check_lowercase(string& str, vector<string>& compares, string mess
}
}
void Circuit::addSimulModel(unsigned id, SimulModel::Base base, SimulModel::Version version, std::string filePath) {
SimulModel* sim = new SimulModel(id, base, version, filePath);
map<unsigned, SimulModel*>::iterator it = _simulModels.find(id);
if (it != _simulModels.end())
throw OpenChamsException("[ERROR] Cannot define two SimulModels' models with the same ID.");
_simulModels[id] = sim;
}
Name Circuit::readParameter(xmlNode* node, double& value) {
xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name");
xmlChar* valueC = xmlGetProp(node, (xmlChar*)"value");
@ -156,6 +167,69 @@ void Circuit::readCircuitParameters(xmlNode* node) {
readCircuitParametersDone = true;
}
void Circuit::readSimulModels(xmlNode* node) {
if (readSimulModelsDone) {
cerr << "[WARNING] Only one 'simulModels' node is allowed in circuit, others will be ignored." << endl;
return;
}
if (node->type == XML_ELEMENT_NODE && node->children) {
for (xmlNode* modelNode = node->children ; modelNode ; modelNode = modelNode->next) {
if (modelNode->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(modelNode->name, (xmlChar*)"model")) {
xmlChar* mIdC = xmlGetProp(modelNode, (xmlChar*)"id");
xmlChar* mBaseC = xmlGetProp(modelNode, (xmlChar*)"base");
xmlChar* mVersionC = xmlGetProp(modelNode, (xmlChar*)"version");
xmlChar* mFilePathC = xmlGetProp(modelNode, (xmlChar*)"filePath");
if (mIdC && mBaseC && mVersionC && mFilePathC) {
unsigned id = ::getValue<unsigned>(mIdC);
SimulModel::Base base = SimulModel::BSIM3V3;
string mBase((const char*)mBaseC);
string baseComp[3] = { "BSIM3V3", "BSIM4", "PSP" };
vector<string> baseComps(baseComp, baseComp+3);
check_uppercase(mBase, baseComps, "[ERROR] SimulModels models' base property must be \"BSIM3V3\", \"BSIM4\" or \"PSP\".");
if (mBase == "BSIM3V3") {
base = SimulModel::BSIM3V3;
} else if (mBase == "BSIM4") {
base = SimulModel::BSIM4;
} else if (mBase == "PSP") {
base = SimulModel::PSP;
} else {
throw OpenChamsException("[ERROR] SimulModels models' base property must be \"BSIM3V3\", \"BSIM4\" or \"PSP\" (check_uppercase should have filtered that).");
return;
}
SimulModel::Version version = SimulModel::UNDEFINED;
string mVersion((const char*)mVersionC);
string verComp[4] = { "UNDEFINED", "SVT", "HVT", "LVT" };
vector<string> verComps(verComp, verComp+4);
check_uppercase(mVersion, verComps, "[ERROR] SimulModels model's version property must be \"UNDEFINED\", \"SVT\", \"HVT\" or \"LVT\".");
if (mVersion == "UNDEFINED") {
version = SimulModel::UNDEFINED;
} else if (mVersion == "SVT") {
version = SimulModel::SVT;
} else if (mVersion == "HVT") {
version = SimulModel::HVT;
} else if (mVersion == "LVT") {
version = SimulModel::LVT;
} else {
throw OpenChamsException("[ERROR] SimulModels models' version property must be \"UNDEFINED\", \"SVT\", \"HVT\" or \"LVT\" (check_uppercase should have filtered that).");
return;
}
string filePath((const char*)mFilePathC);
addSimulModel(id, base, version, filePath);
// Ce simuModel DOIT être rataché au circuit !!!
} else {
throw OpenChamsException("[ERROR] 'model' node must have 'id', 'base', 'version' and 'filePath' properties.");
}
} else {
cerr << "[WARNING] Only 'model' nodes are allowed under 'simulModels' node." << endl;
return;
}
}
}
}
readSimulModelsDone = true;
}
// NETLIST //
void Circuit::readNetList(xmlNode* node) {
if (readNetListDone) {
@ -189,9 +263,7 @@ void Circuit::readInstances(xmlNode* node, Netlist* netlist) {
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);
if (inst)
netlist->addInstance(inst);
readInstance(node, netlist);
} else {
cerr << "[WARNING] Only 'instance' nodes are allowed in 'instances', others will be ignored." << endl;
}
@ -218,7 +290,7 @@ Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) {
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);
inst = netlist->addInstance(instanceName, modelName, Name(mosStr), sourceBulkConnected);
} else {
throw OpenChamsException("[ERROR] 'instance' node must have 'name', 'model', 'mostype' and 'sourceBulkConnected' properties.");
//return inst;
@ -296,7 +368,7 @@ void Circuit::readTransistor(xmlNode* node, Instance* inst) {
Transistor* trans = NULL;
if (tNameC) {
Name tName((const char*)tNameC);
trans = new Transistor(tName, inst);
trans = inst->addTransistor(tName);
} else {
throw OpenChamsException("[ERROR] 'transistor' node must have 'name' property.");
//return inst;
@ -314,7 +386,6 @@ void Circuit::readTransistor(xmlNode* node, Instance* inst) {
}
}
}
inst->addTransistor(trans);
}
void Circuit::readTransistorConnection(xmlNode* node, Transistor* trans) {
@ -372,8 +443,7 @@ Net* Circuit::readNet(xmlNode* node, Netlist* netlist) {
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);
net = netlist->addNet(netName, Name(typeStr), isExternal);
} else {
throw OpenChamsException("[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties.");
//return net;
@ -385,7 +455,7 @@ Net* Circuit::readNet(xmlNode* node, Netlist* netlist) {
if (xmlStrEqual(node->name, (xmlChar*)"connector")) {
readNetConnector(node, net);
} else {
cerr << "[WARNING] Only 'conector' nodes are allowed in 'net', others will be ignored." << endl;
cerr << "[WARNING] Only 'connector' nodes are allowed in 'net', others will be ignored." << endl;
return NULL;
}
}
@ -602,15 +672,25 @@ Circuit* Circuit::readFromFile(const string filePath) {
if (xmlStrEqual(node->name, (xmlChar*)"parameters")) {
cir->readCircuitParameters(node);
}
if (xmlStrEqual(node->name, (xmlChar*)"netlist")) {
else if (xmlStrEqual(node->name, (xmlChar*)"simulModels")) {
cir->readSimulModels(node);
}
else if (xmlStrEqual(node->name, (xmlChar*)"netlist")) {
cir->readNetList(node);
}
if (xmlStrEqual(node->name, (xmlChar*)"schematic")) {
else if (xmlStrEqual(node->name, (xmlChar*)"schematic")) {
cir->readSchematic(node);
}
if (xmlStrEqual(node->name, (xmlChar*)"sizing")) {
else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) {
cir->readSizing(node);
}
else {
string error("[ERROR] Unknown section ");
error += string((const char*)node->name);
error += " in circuit description.";
throw OpenChamsException(error);
return NULL;
}
}
}
}
@ -620,6 +700,39 @@ Circuit* Circuit::readFromFile(const string filePath) {
return cir;
}
Netlist* Circuit::createNetlist() {
if (_netlist)
throw OpenChamsException("[ERROR] Cannot create two netlists in one circuit.");
_netlist = new Netlist(this);
if (!_netlist)
throw OpenChamsException("[ERROR] Cannot create netlist.");
return _netlist;
}
Schematic* Circuit::createSchematic(double zoom) {
if (_schematic)
throw OpenChamsException("[ERROR] Cannot create two scheamtics in one circuit.");
_schematic = new Schematic(this, zoom);
if (!_schematic)
throw OpenChamsException("[ERROR] Cannot create schematic.");
return _schematic;
}
Sizing* Circuit::createSizing() {
if (_sizing)
throw OpenChamsException("[ERROR] Cannot create two sizings in one circuit.");
_sizing = new Sizing(this);
if (!_sizing)
throw OpenChamsException("[ERROR] Cannot create sizing.");
return _sizing;
}
bool Circuit::writeToFile(string filePath) {
ofstream file;
file.open(filePath.c_str());
@ -708,7 +821,7 @@ bool Circuit::writeToFile(string filePath) {
sort(nets.begin(), nets.end(), NetNameSort); // sort based on nets' names
for (vector<Net*>::iterator it = nets.begin() ; it != nets.end() ; ++it) {
Net* net = (*it);
if (net->hasNoConnectors()) {
if (net->hasNoConnections()) {
string error("[ERROR] Cannot writeToFile since net (");
error += net->getName().getString();
error += ") has no connectors !";
@ -717,10 +830,10 @@ bool Circuit::writeToFile(string filePath) {
}
string externStr = (net->isExternal()) ? "True" : "False";
file << " <net name=\"" << net->getName().getString() << "\" type=\"" << net->getType().getString() << "\" isExternal=\"" << externStr << "\">" << endl;
vector<pair<Name, Name> > connections = net->getConnections();
vector<Net::Connection*> connections = net->getConnections();
sort(connections.begin(), connections.end(), ConnectionsSort);
for (vector<pair<Name, Name> >::iterator it = connections.begin() ; it != connections.end() ; ++it) {
file << " <connector instance=\"" << (*it).first.getString() << "\" name=\"" << (*it).second.getString() << "\"/>" << endl;
for (vector<Net::Connection*>::iterator it = connections.begin() ; it != connections.end() ; ++it) {
file << " <connector instance=\"" << (*it)->getInstanceName().getString() << "\" name=\"" << (*it)->getConnectorName().getString() << "\"/>" << endl;
}
file << " </net>" << endl;
}
@ -730,7 +843,7 @@ bool Circuit::writeToFile(string filePath) {
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 << " <instance name=\"" << ((*it).first).getString() << "\" x=\"" << infos->getX() << "\" y=\"" << infos->getY() << "\" sym=\"" << infos->getSymmetry().getString() << "\"/>" << endl;
}
file << " </schematic>" << endl;
}

View File

@ -22,13 +22,17 @@ Instance::Instance(Name name, Name model, Name mosType, bool sourceBulkConnected
, _model(model)
, _mosType(mosType)
, _sourceBulkConnected(sourceBulkConnected)
, _netlist(netlist) {}
, _netlist(netlist)
, _params()
, _netMap()
, _trans() {}
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())
if (it == _netMap.end()) {
_netMap[name] = NULL;
}
else {
string error("[ERROR] The same instance cannot have several connectors with same name (");
error += name.getString();
@ -60,5 +64,14 @@ void Instance::connect(Name connectorName, Name netName) {
throw OpenChamsException(error);
}
}
Transistor* Instance::addTransistor(Name name) {
Transistor* tr = new Transistor(name, this);
if (!tr)
throw OpenChamsException("[ERROR] Cannot create transistor.");
_trans.push_back(tr);
return tr;
}
}

View File

@ -15,6 +15,18 @@ namespace OpenChams {
unsigned long Name::_globalId = 0;
map<string, unsigned long> Name::_dict;
Name::Name() : _str(NULL) {
map<string, unsigned long>::iterator it = _dict.find("");
if (it != _dict.end()) {
_id = (*it).second;
_str = &((*it).first);
} else {
_id = _globalId++;
it = _dict.insert(_dict.begin(), make_pair("", _id));
_str = &((*it).first);
}
}
Name::Name(string str) : _str(NULL) {
map<string, unsigned long>::iterator it = _dict.find(str);
if (it != _dict.end()) {

View File

@ -10,7 +10,9 @@
using namespace std;
#include "vlsisapd/openChams/Net.h"
#include "vlsisapd/openChams/Instance.h"
#include "vlsisapd/openChams/Netlist.h"
#include "vlsisapd/openChams/OpenChamsException.h"
namespace OpenChams {
Net::Net(Name netName, Name typeName, bool isExternal, Netlist* netlist)
@ -20,6 +22,19 @@ Net::Net(Name netName, Name typeName, bool isExternal, Netlist* netlist)
, _netlist(netlist) {}
void Net::connectTo(Name instanceName, Name connectorName) {
_connections.push_back(pair<Name, Name>(instanceName, connectorName));
_connections.push_back(new Net::Connection(instanceName, connectorName));
Instance* inst = _netlist->getInstance(instanceName);
if (!inst) {
string error ("[ERROR] While connecting net ");
error += _name.getString();
error += " to instance ";
error += instanceName.getString();
error += ": instance does not exist in netlist !";
throw OpenChamsException(error);
} else {
inst->connect(connectorName, _name);
}
}
Net::Connection::Connection(Name instanceName, Name connectorName) : _instanceName(instanceName), _connectorName(connectorName) {}
} // namespace

View File

@ -20,28 +20,39 @@ using namespace std;
namespace OpenChams {
Netlist::Netlist(Circuit* circuit) : _circuit(circuit) {}
void Netlist::addInstance(Instance* inst) {
Instance* Netlist::addInstance(Name name, Name model, Name mosType, bool sourceBulkConnected) {
for (vector<Instance*>::iterator it = _instances.begin() ; it != _instances.end() ; ++it) {
if ((*it)->getName() == inst->getName()) {
if ((*it)->getName() == name) {
string error("[ERROR] Cannot define two instances with the same name in netlist (");
error += inst->getName().getString();
error += name.getString();
error += ").";
throw OpenChamsException(error);
}
}
Instance* inst = new Instance(name, model, mosType, sourceBulkConnected, this);
if (!inst)
throw OpenChamsException("[ERROR] Cannot creeate instance.");
_instances.push_back(inst);
return inst;
}
void Netlist::addNet(Net* net) {
Net* Netlist::addNet(Name name, Name type, bool external) {
for (vector<Net*>::iterator it = _nets.begin() ; it != _nets.end() ; ++it ) {
if ((*it)->getName() == net->getName()) {
if ((*it)->getName() == name) {
string error("[ERROR] Cannot define two nets with the same name in netlist (");
error += net->getName().getString();
error += name.getString();
error += ").";
throw OpenChamsException(error);
}
}
Net* net = new Net(name, type, external, this);
if (!net)
throw OpenChamsException("[ERROR] Cannot create net.");
_nets.push_back(net);
return net;
}
Instance* Netlist::getInstance(Name instanceName) {

View File

@ -19,6 +19,10 @@ Operator::Operator(Name operatorName, Name simulModel, unsigned callOrder)
, _simulModel(simulModel)
, _callOrder(callOrder) {}
void Operator::addConstraint(Name paramName, Name ref, Name refParam) {
addConstraint(paramName, ref, refParam, 1.0);
}
void Operator::addConstraint(Name paramName, Name ref, Name refParam, double factor) {
map<Name, Constraint*>::iterator it = _constraints.find(paramName);
if (it != _constraints.end()) {
@ -30,6 +34,10 @@ void Operator::addConstraint(Name paramName, Name ref, Name refParam, double fac
_constraints[paramName] = new Operator::Constraint(ref, refParam, factor);
}
void Operator::addConstraint(Name paramName, Name refEquation) {
addConstraint(paramName, refEquation, 1.0);
}
void Operator::addConstraint(Name paramName, Name refEquation, double factor) {
map<Name, Constraint*>::iterator it = _constraints.find(paramName);
if (it != _constraints.end()) {

View File

@ -26,6 +26,16 @@ double Parameters::getValue(Name name) {
}
return (*it).second;
}
std::string Parameters::getEqValue(Name name) {
map<Name, string>::iterator it = _paramsEq.find(name);
if (it == _paramsEq.end()) {
string error("[ERROR] No parameters named ");
error += name.getString();
throw OpenChamsException(error);
}
return (*it).second;
}
void Parameters::addParameter(Name name, double value) {
map<Name, double>::iterator it = _params.find(name);

View File

@ -0,0 +1,267 @@
using namespace std;
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
using namespace boost::python;
#include "vlsisapd/openChams/Name.h"
#include "vlsisapd/openChams/Parameters.h"
#include "vlsisapd/openChams/Transistor.h"
#include "vlsisapd/openChams/Instance.h"
#include "vlsisapd/openChams/Net.h"
#include "vlsisapd/openChams/Netlist.h"
#include "vlsisapd/openChams/Schematic.h"
#include "vlsisapd/openChams/Operator.h"
#include "vlsisapd/openChams/SimulModel.h"
#include "vlsisapd/openChams/Sizing.h"
#include "vlsisapd/openChams/Circuit.h"
#include "vlsisapd/openChams/OpenChamsException.h"
#include "vlsisapd/openChams/PySTLMapWrapper.h"
namespace OpenChams {
void translator(OpenChamsException const& e) {
PyErr_SetString(PyExc_UserWarning, e.what());
}
BOOST_PYTHON_MODULE(pyOPENCHAMS) {
// class OpenChams::Name
class_<Name>("Name", init<std::string>())
.def(init<>())
// accessors
.def("getString", &Name::getString, return_value_policy<copy_const_reference>()) // return_value_policy because this method return a refenrce on string
.def("__repr__" , &Name::getString, return_value_policy<copy_const_reference>()) // automatic print for Name object
// operators
.def(self == self)
.def(self == std::string())
.def(self < self)
;
implicitly_convertible<std::string, Name>();
// map wrapping for OpenChams::Parameters
STL_MAP_WRAPPING(Name, double , "ValuesMap" )
STL_MAP_WRAPPING(Name, std::string, "EquationsMap")
// class OpenChams::Parameters
class_<Parameters>("Parameters", init<>())
// accessors
.def("getValue" , &Parameters::getValue )
.def("getEqValue" , &Parameters::getEqValue)
.def("isEmpty" , &Parameters::isEmpty )
// modifiers
.def("addParameter", static_cast<void(Parameters::*)(Name, double )>(&Parameters::addParameter))
.def("addParameter", static_cast<void(Parameters::*)(Name, std::string)>(&Parameters::addParameter))
// stl containers
.def("getValues" , &Parameters::getValues , return_value_policy<copy_const_reference>())
.def("getEqValues" , &Parameters::getEqValues, return_value_policy<copy_const_reference>())
;
{ //this scope is used to define Base as a subenum of SimulModel
// class OpenChams::SimulModel
scope simMod = class_<SimulModel>("SimulModel", init<unsigned, SimulModel::Base, SimulModel::Version, std::string>())
// properties
.add_property("id" , &SimulModel::getId )
.add_property("base" , &SimulModel::getBase )
.add_property("version" , &SimulModel::getVersion )
.add_property("filePath", &SimulModel::getFilePath)
;
enum_<SimulModel::Base>("Base")
.value("BSIM3V3", SimulModel::BSIM3V3)
.value("BSIM4" , SimulModel::BSIM4 )
.value("PSP" , SimulModel::PSP )
;
enum_<SimulModel::Version>("Version")
.value("UNDEFINED", SimulModel::UNDEFINED)
.value("SVT" , SimulModel::SVT )
.value("HVT" , SimulModel::HVT )
.value("LVT" , SimulModel::LVT )
;
}
// class OpenChams::Transistor
class_<Transistor, Transistor*>("Transistor", init<Name, Instance*>())
// properties
.add_property("name" , &Transistor::getName , &Transistor::setName )
.add_property("gate" , &Transistor::getGate , &Transistor::setGate )
.add_property("source" , &Transistor::getSource , &Transistor::setSource)
.add_property("drain" , &Transistor::getDrain , &Transistor::setDrain )
.add_property("bulk" , &Transistor::getBulk , &Transistor::setBulk )
.add_property("parameters", &Transistor::getParameters ) // no setter => params will be readonly
// modifiers
.def("addParameter", static_cast<void(Transistor::*)(Name, double )>(&Transistor::addParameter))
.def("addParameter", static_cast<void(Transistor::*)(Name, std::string)>(&Transistor::addParameter))
;
// map wrapping and vector_indexing for OpenChams::Instance
STL_MAP_WRAPPING_PTR(Name, Net*, "ConnectorsMap")
class_<std::vector<Transistor*> >("TransistorsVector")
.def(vector_indexing_suite<std::vector<Transistor*>, true>())
;
// class OpenChams::Instance
class_<Instance, Instance*>("Instance", init<Name, Name, Name, bool, Netlist*>())
// properties
.add_property("name" , &Instance::getName )
.add_property("model" , &Instance::getModel )
.add_property("mosType" , &Instance::getMosType )
.add_property("sourceBulkConnected", &Instance::isSourceBulkConnected)
.add_property("parameters" , &Instance::getParameters )
.add_property("netlist" , make_function(&Instance::getNetlist ,return_value_policy<reference_existing_object>())) //make_function since we need to specify a return value policy
// accessors
.def("hasNoConnectors" , &Instance::hasNoConnectors )
.def("hasNoTransistors", &Instance::hasNoTransistors)
// modifiers
.def("addConnector" , &Instance::addConnector )
.def("connect" , &Instance::connect )
.def("addTransistor", &Instance::addTransistor, return_value_policy<reference_existing_object>())
.def("addParameter" , static_cast<void(Transistor::*)(Name, double )>(&Transistor::addParameter))
.def("addParameter" , static_cast<void(Transistor::*)(Name, std::string)>(&Transistor::addParameter))
// stl containers
.def("getConnectors" , &Instance::getConnectors , return_internal_reference<>())
.def("getTransistors", &Instance::getTransistors, return_internal_reference<>())
;
// vector_indexing for OpenChams::Net
class_<std::vector<Net::Connection*> >("ConnectionsVector")
.def(vector_indexing_suite<std::vector<Net::Connection*>, true>())
;
{ //this scope is used to define Connection as a subclass of Net
// class OpenChams::Net
scope netScope = class_<Net, Net*>("Net", init<Name, Name, bool, Netlist*>())
// properties
.add_property("name" , &Net::getName )
.add_property("type" , &Net::getType )
.add_property("external", &Net::isExternal)
.add_property("netlist" , make_function(&Net::getNetlist, return_value_policy<reference_existing_object>()))
// accessors
.def("hasNoConnections", &Net::hasNoConnections)
// modifiers
.def("connectTo" , &Net::connectTo )
// stl containers
.def("getConnections", &Net::getConnections, return_internal_reference<>())
;
// class OpenChams::Net::Connection
class_<Net::Connection, Net::Connection*>("Connection", init<Name, Name>())
.add_property("instanceName" , &Net::Connection::getInstanceName )
.add_property("connectorName", &Net::Connection::getConnectorName)
;
} // end netScope
// vector_indexing for OpenChams::Netlist
class_<std::vector<Instance*> >("InstancesVector")
.def(vector_indexing_suite<std::vector<Instance*>, true>())
;
class_<std::vector<Net*> >("NetsVector")
.def(vector_indexing_suite<std::vector<Net*>, true>())
;
// class OpenChams::Netlist
class_<Netlist, Netlist*>("Netlist", init<Circuit*>())
// accessors
.def("hasNoInstances", &Netlist::hasNoInstances)
.def("hasNoNets" , &Netlist::hasNoNets )
.def("getInstance" , make_function(&Netlist::getInstance , return_value_policy<reference_existing_object>()))
.def("getNet" , make_function(&Netlist::getNet , return_value_policy<reference_existing_object>()))
// modifiers
.def("addInstance", &Netlist::addInstance, return_value_policy<reference_existing_object>())
.def("addNet" , &Netlist::addNet , return_value_policy<reference_existing_object>())
// stl containers
.def("getInstances", &Netlist::getInstances, return_internal_reference<>())
.def("getNets" , &Netlist::getNets , return_internal_reference<>())
;
// map wrapping for OpenChams::Schematic
STL_MAP_WRAPPING_PTR(Name, Schematic::Infos*, "SchematicInstancesMap")
{ // this scope is used to define Infos as a subclass of Schematic
// class OpenChams::Schematic
scope schematicScope = class_<Schematic, Schematic*>("Schematic", init<Circuit*, double>())
// properties
.add_property("zoom", &Schematic::getZoom)
// accessors
.def("hasNoInstances", &Schematic::hasNoInstances)
// modifiers
.def("addInstance", &Schematic::addInstance)
// stl containers
.def("getInstances", &Schematic::getInstances, return_internal_reference<>())
;
// class OpenChams::Schematic::Infos
class_<Schematic::Infos, Schematic::Infos*>("Infos", init<double, double, Name>())
.add_property("x" , &Schematic::Infos::getX )
.add_property("y" , &Schematic::Infos::getY )
.add_property("symmetry", &Schematic::Infos::getSymmetry)
;
} // end schematicScope
// map wrapping for OpenChams::Operator
STL_MAP_WRAPPING_PTR(Name, Operator::Constraint*, "ConstraintsMap")
{ // this scope is used to define Constraint as a subclass of Operator
// class OpenChams::Operator
scope operatorScope = class_<Operator, Operator*>("Operator", init<Name, Name, unsigned>())
// properties
.add_property("name" , &Operator::getName )
.add_property("simulModel", &Operator::getSimulModel)
.add_property("callOrder" , &Operator::getCallOrder )
// accessors
.def("hasNoConstraints", &Operator::hasNoConstraints)
// modifiers
.def("addConstraint", static_cast<void(Operator::*)(Name, Name )>(&Operator::addConstraint))
.def("addConstraint", static_cast<void(Operator::*)(Name, Name, double )>(&Operator::addConstraint))
.def("addConstraint", static_cast<void(Operator::*)(Name, Name, Name )>(&Operator::addConstraint))
.def("addConstraint", static_cast<void(Operator::*)(Name, Name, Name, double)>(&Operator::addConstraint))
// stl containers
.def("getConstraints", &Operator::getConstraints, return_internal_reference<>())
;
// class OpenChams::Operator::Constraint
class_<Operator::Constraint, Operator::Constraint*>("Constraint", init<Name, Name, double>())
.add_property("ref" , &Operator::Constraint::getRef )
.add_property("refParam", &Operator::Constraint::getRefParam)
.add_property("factor" , &Operator::Constraint::getFactor )
;
} // end operatorScope
// map wrapping for OpenChams::Sizing
STL_MAP_WRAPPING_PTR(Name, Operator*, "OperatorsMap")
// class OpenChams::Sizing
class_<Sizing, Sizing*>("Sizing", init<Circuit*>())
// accessors
.def("hasNoEquations", &Sizing::hasNoEquations)
.def("hasNoOperators", &Sizing::hasNoOperators)
// modifiers
.def("addEquation", &Sizing::addEquation)
.def("addOperator", &Sizing::addOperator, return_value_policy<reference_existing_object>())
// stl containers
.def("getEquations", &Sizing::getEquations, return_internal_reference<>())
.def("getOperators", &Sizing::getOperators, return_internal_reference<>())
;
class_<Circuit, Circuit*>("Circuit", init<Name, Name>())
// properties
.add_property("name" , &Circuit::getName )
.add_property("techno" , &Circuit::getTechno )
.add_property("parameters", &Circuit::getParameters)
.add_property("netlist" , make_function(&Circuit::getNetlist , return_value_policy<reference_existing_object>()))
.add_property("schematic" , make_function(&Circuit::getSchematic, return_value_policy<reference_existing_object>()))
.add_property("sizing" , make_function(&Circuit::getSizing , return_value_policy<reference_existing_object>()))
// accessors
.def("getValue", &Circuit::getValue)
// modifiers
.def("createNetlist" , &Circuit::createNetlist , return_value_policy<reference_existing_object>())
.def("createSchematic", &Circuit::createSchematic, return_value_policy<reference_existing_object>())
.def("createSizing" , &Circuit::createSizing , return_value_policy<reference_existing_object>())
.def("addParameter", static_cast<void(Circuit::*)(Name, double )>(&Circuit::addParameter))
.def("addParameter", static_cast<void(Circuit::*)(Name, std::string)>(&Circuit::addParameter))
// others
.def("readFromFile", &Circuit::readFromFile, return_value_policy<manage_new_object>())
.staticmethod("readFromFile")
.def("writeToFile" , &Circuit::writeToFile)
;
// OpenChamsException translator
register_exception_translator<OpenChamsException>(translator)
;
}
}

View File

@ -0,0 +1,21 @@
/*
* SimulModel.cpp
* openChams
*
* Created by damien dupuis on 06/07/10.
* Copyright 2010 UPMC / LIP6. All rights reserved.
*
*/
using namespace std;
#include "vlsisapd/openChams/SimulModel.h"
namespace OpenChams {
SimulModel::SimulModel(unsigned id, SimulModel::Base base, SimulModel::Version version, std::string filePath)
: _id(id)
, _base(base)
, _version(version)
, _filePath(filePath) {}
} // namespace

View File

@ -11,12 +11,14 @@
#define __OPENCHAMS_CIRCUIT_H__
#include <vector>
#include <map>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "vlsisapd/openChams/Name.h"
#include "vlsisapd/openChams/Parameters.h"
#include "vlsisapd/openChams/SimulModel.h"
namespace OpenChams {
class Netlist;
@ -40,10 +42,14 @@ class Circuit {
inline void addParameter(Name, double);
inline void addParameter(Name, std::string);
inline Parameters getParameters();
void addSimulModel(unsigned, SimulModel::Base, SimulModel::Version, std::string);
inline void setNetlist(Netlist*);
inline void setSchematic(Schematic*);
inline void setSizing(Sizing*);
Netlist* createNetlist();
Schematic* createSchematic(double);
Sizing* createSizing();
bool writeToFile(std::string filePath);
static Circuit* readFromFile(const std::string filePath);
@ -53,6 +59,7 @@ class Circuit {
Name readParameterEq(xmlNode*, std::string&);
Name readConnector(xmlNode*);
void readCircuitParameters(xmlNode*);
void readSimulModels(xmlNode*);
void readNetList(xmlNode*);
void readInstances(xmlNode*, Netlist*);
Instance* readInstance (xmlNode*, Netlist*);
@ -81,6 +88,7 @@ class Circuit {
Netlist* _netlist;
Schematic* _schematic;
Sizing* _sizing;
map<unsigned, SimulModel*> _simulModels;
};
inline Name Circuit::getName() { return _name; };
@ -92,9 +100,6 @@ inline Sizing* Circuit::getSizing() { return _sizing; };
inline void Circuit::addParameter(Name name, double value) { _params.addParameter(name, value); };
inline void Circuit::addParameter(Name name, std::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 OpenChams

View File

@ -27,15 +27,13 @@ class Instance {
void addConnector(Name);
void connect(Name connectorName, Name netName);
Instance* getInstance(Name);
inline void addParameter(Name, double);
inline void addParameter(Name, std::string);
inline void addTransistor(Transistor*);
inline Name getName() const;
inline Name getModel();
inline Name getMosType();
inline bool isSourceBulkConnected();
inline Netlist* getNetlist();
inline Parameters getParameters();
// pour parcourir les connecteurs
inline bool hasNoConnectors();
@ -44,6 +42,8 @@ class Instance {
inline bool hasNoTransistors();
inline const std::vector<Transistor*>& getTransistors();
Transistor* addTransistor(Name);
private:
Name _name;
Name _model;
@ -57,11 +57,11 @@ 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 void Instance::addTransistor(Transistor* tr) { _trans.push_back(tr); };
inline Name Instance::getName() const { return _name; };
inline Name Instance::getModel() { return _model; };
inline Name Instance::getMosType() { return _mosType; };
inline bool Instance::isSourceBulkConnected() { return _sourceBulkConnected; };
inline Netlist* Instance::getNetlist() { return _netlist; };
inline Parameters Instance::getParameters() { return _params; };
inline bool Instance::hasNoConnectors() { return (_netMap.size() == 0)? true : false; };
inline const std::map<Name, Net*>& Instance::getConnectors() { return _netMap; };

View File

@ -18,6 +18,7 @@
namespace OpenChams {
class Name {
public:
Name();
Name(std::string);
Name(const char*);

View File

@ -17,6 +17,19 @@
namespace OpenChams {
class Netlist;
class Net {
public:
class Connection {
public:
Connection(Name instanceName, Name connectorName);
inline Name getInstanceName() const;
inline Name getConnectorName() const;
private:
Name _instanceName;
Name _connectorName;
};
public:
Net(Name netName, Name typeName, bool, Netlist*);
@ -26,27 +39,30 @@ class Net {
inline Name getType();
inline bool isExternal();
inline Netlist* getNetlist();
inline bool hasNoConnectors();
inline bool hasNoConnections();
//inline vector<pair<Name, Name> >::iterator getFirstConnectionIt();
//inline vector<pair<Name, Name> >::iterator getLastConnectionIt();
inline const std::vector<std::pair<Name, Name> >& getConnections();
inline const std::vector<Net::Connection*>& getConnections();
private:
Name _name;
Name _typeName;
bool _isExternal;
Netlist* _netlist;
std::vector<std::pair<Name, Name> > _connections; // <instanceName, connectorName>
std::vector<Net::Connection*> _connections; // <instanceName, connectorName>
};
inline Name Net::getName() const { 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 bool Net::hasNoConnections() { 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 const std::vector<std::pair<Name, Name> >& Net::getConnections() { return _connections; };
inline const std::vector<Net::Connection*>& Net::getConnections() { return _connections; };
inline Name Net::Connection::getInstanceName() const { return _instanceName; };
inline Name Net::Connection::getConnectorName() const { return _connectorName; };
} // namespace
#endif

View File

@ -22,8 +22,8 @@ class Netlist {
public:
Netlist(Circuit*);
void addInstance(Instance*);
void addNet(Net*);
Instance* addInstance(Name name, Name model, Name mosType, bool);
Net* addNet (Name name, Name type , bool);
Instance* getInstance(Name);
Net* getNet(Name);

View File

@ -34,8 +34,10 @@ class Operator {
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);
void addConstraint(Name paramName, Name ref, Name refParam );
void addConstraint(Name paramName, Name ref, Name refParam, double factor);
void addConstraint(Name paramName, Name refEquation );
void addConstraint(Name paramName, Name refEquation, double factor);
inline Name getName();
inline Name getSimulModel();

View File

@ -0,0 +1,87 @@
#include <map>
#include <boost/python.hpp>
namespace OpenChams {
// since we want to wrap std::map<type, Class*> with cimple pointers (no boost::shared_ptr),
// we cannot use map_indexing_suite which has not the right return_value_policy.
// std::maps with no points value are wrapped using map_indexing_suite technique.
//
// This templated map_item struct is intended to be used for 'manual' wrapping:
template<class Key, class Val>
struct map_item {
typedef std::map<Key,Val> Map;
static Val get(Map & self, const Key idx) {
if (self.find(idx) == self.end()) {
PyErr_SetString(PyExc_KeyError,"Map key not found");
throw_error_already_set();
}
return self[idx];
}
static void set(Map& self, const Key idx, const Val val) { self[idx]=val; }
static void del(Map& self, const Key n) { self.erase(n); }
static bool in (Map const& self, const Key n) { return self.find(n) != self.end(); }
static list keys(Map const& self) {
list t;
for(typename Map::const_iterator it = self.begin() ; it!=self.end() ; ++it)
t.append(it->first);
return t;
}
static list values(Map const& self) {
list t;
for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it)
t.append(it->second);
return t;
}
static list items(Map const& self) {
list t;
for(typename Map::const_iterator it=self.begin(); it!=self.end(); ++it)
t.append( make_tuple(it->first, it->second) );
return t;
}
};
#define STL_MAP_WRAPPING_PTR(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME) \
class_<std::pair<const KEY_TYPE, VALUE_TYPE> >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \
.def_readonly ("key" , &std::pair<const KEY_TYPE, VALUE_TYPE>::first ) \
.def_readwrite("value", &std::pair<const KEY_TYPE, VALUE_TYPE>::second) \
; \
class_<std::map<KEY_TYPE, VALUE_TYPE> >(PYTHON_TYPE_NAME) \
.def("__len__" , &std::map<KEY_TYPE, VALUE_TYPE>::size) \
.def("__iter__" , boost::python::iterator<std::map<KEY_TYPE, VALUE_TYPE>, return_internal_reference<> >()) \
.def("__getitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().get, return_internal_reference<>()) \
.def("__setitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().set ) \
.def("__delitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().del ) \
.def("__contains__", &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
.def("clear" , &std::map<KEY_TYPE, VALUE_TYPE>::clear ) \
.def("has_key" , &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
.def("keys" , &map_item<KEY_TYPE, VALUE_TYPE>().keys ) \
.def("values" , &map_item<KEY_TYPE, VALUE_TYPE>().values) \
.def("items" , &map_item<KEY_TYPE, VALUE_TYPE>().items ) \
;
#define STL_MAP_WRAPPING(KEY_TYPE, VALUE_TYPE, PYTHON_TYPE_NAME) \
class_<std::pair<const KEY_TYPE, VALUE_TYPE> >((std::string(PYTHON_TYPE_NAME)+std::string("DATA")).c_str()) \
.def_readonly ("key" , &std::pair<const KEY_TYPE, VALUE_TYPE>::first ) \
.def_readwrite("value", &std::pair<const KEY_TYPE, VALUE_TYPE>::second) \
; \
class_<std::map<KEY_TYPE, VALUE_TYPE> >(PYTHON_TYPE_NAME) \
.def("__len__" , &std::map<KEY_TYPE, VALUE_TYPE>::size) \
.def("__iter__" , boost::python::iterator<std::map<KEY_TYPE, VALUE_TYPE>, return_internal_reference<> >()) \
.def("__getitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().get ) \
.def("__setitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().set ) \
.def("__delitem__" , &map_item<KEY_TYPE, VALUE_TYPE>().del ) \
.def("__contains__", &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
.def("clear" , &std::map<KEY_TYPE, VALUE_TYPE>::clear ) \
.def("has_key" , &map_item<KEY_TYPE, VALUE_TYPE>().in ) \
.def("keys" , &map_item<KEY_TYPE, VALUE_TYPE>().keys ) \
.def("values" , &map_item<KEY_TYPE, VALUE_TYPE>().values) \
.def("items" , &map_item<KEY_TYPE, VALUE_TYPE>().items ) \
;
} // namespace

View File

@ -25,7 +25,7 @@ class Schematic {
inline double getX();
inline double getY();
inline Name getSymetry();
inline Name getSymmetry();
private:
double _x;
@ -51,9 +51,9 @@ 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; };
inline double Schematic::Infos::getX() { return _x; };
inline double Schematic::Infos::getY() { return _y; };
inline Name Schematic::Infos::getSymmetry() { return _sym; };
} // namespace
#endif

View File

@ -0,0 +1,49 @@
/*
* SimulModel.h
* openChams
*
* Created by damien dupuis on 06/07/10.
* Copyright 2010 UPMC / LIP6. All rights reserved.
*
*/
#ifndef __OPENCHAMS_SIMULMODEL_H__
#define __OPENCHAMS_SIMULMODEL_H__
#include "vlsisapd/openChams/Name.h"
namespace OpenChams {
class SimulModel {
public:
enum Base { BSIM3V3=0,
BSIM4=1,
PSP=2
};
enum Version { UNDEFINED=0,
SVT=1,
HVT=2,
LVT=3
};
SimulModel(unsigned, Base, Version, std::string);
inline unsigned getId() const;
inline Base getBase();
inline Version getVersion();
inline std::string getFilePath();
private:
unsigned _id;
Base _base;
Version _version;
std::string _filePath;
};
inline unsigned SimulModel::getId() const { return _id; };
inline SimulModel::Base SimulModel::getBase() { return _base; };
inline SimulModel::Version SimulModel::getVersion() { return _version; };
inline std::string SimulModel::getFilePath() { return _filePath;};
} // namespace
#endif