Added support to transistor in instance so we can reach transistor level in netlist.

This commit is contained in:
Damien Dupuis 2010-03-02 13:25:31 +00:00
parent e9e60fea07
commit feef029cae
7 changed files with 261 additions and 23 deletions

View File

@ -1,7 +1,28 @@
INCLUDE_DIRECTORIES(${CHAMS_SOURCE_DIR}/openChams ${LIBXML2_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${CHAMS_SOURCE_DIR}/openChams ${LIBXML2_INCLUDE_DIR})
SET ( includes Circuit.h Netlist.h Instance.h Net.h Name.h Operator.h Parameters.h Schematic.h Sizing.h OpenChamsException.h ) SET ( includes
SET ( cpps Circuit.cpp Netlist.cpp Instance.cpp Net.cpp Name.cpp Operator.cpp Parameters.cpp Schematic.cpp Sizing.cpp ) Circuit.h
Netlist.h
Instance.h
Net.h
Name.h
Operator.h
Parameters.h
Schematic.h
Sizing.h
Transistor.h
OpenChamsException.h )
SET ( cpps
Circuit.cpp
Netlist.cpp
Instance.cpp
Net.cpp
Name.cpp
Operator.cpp
Parameters.cpp
Schematic.cpp
Sizing.cpp
Transistor.cpp )
ADD_LIBRARY(openChams ${cpps}) ADD_LIBRARY(openChams ${cpps})

View File

@ -45,6 +45,7 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis
readSizingDone = false; readSizingDone = false;
} }
// USEFUL //
void Circuit::check_uppercase(string& str, vector<string>& compares, string message) { void Circuit::check_uppercase(string& str, vector<string>& compares, string message) {
transform(str.begin(), str.end(), str.begin(), ::toupper); transform(str.begin(), str.end(), str.begin(), ::toupper);
bool equal = false; bool equal = false;
@ -105,7 +106,8 @@ Name Circuit::readConnector(xmlNode* node) {
//return Name(""); //return Name("");
} }
} }
// CIRCUIT //
void Circuit::readCircuitParameters(xmlNode* node) { void Circuit::readCircuitParameters(xmlNode* node) {
if (readCircuitParametersDone) { if (readCircuitParametersDone) {
cerr << "[WARNING] Only one 'parameters' node is allowed in circuit, others will be ignored." << endl; cerr << "[WARNING] Only one 'parameters' node is allowed in circuit, others will be ignored." << endl;
@ -134,6 +136,7 @@ void Circuit::readCircuitParameters(xmlNode* node) {
readCircuitParametersDone = true; readCircuitParametersDone = true;
} }
// NETLIST //
void Circuit::readNetList(xmlNode* node) { void Circuit::readNetList(xmlNode* node) {
if (readNetListDone) { if (readNetListDone) {
cerr << "[WARNING] Only one 'netlist' node is allowed in circuit, others will be ignored." << endl; cerr << "[WARNING] Only one 'netlist' node is allowed in circuit, others will be ignored." << endl;
@ -155,7 +158,8 @@ void Circuit::readNetList(xmlNode* node) {
readNetListDone = true; readNetListDone = true;
_netlist = netlist; _netlist = netlist;
} }
// INSTANCES //
void Circuit::readInstances(xmlNode* node, Netlist* netlist) { void Circuit::readInstances(xmlNode* node, Netlist* netlist) {
if (readInstancesDone) { if (readInstancesDone) {
cerr << "[WARNING] Only one 'instances' node is allowed in 'netlist', others will be ignored." << endl; cerr << "[WARNING] Only one 'instances' node is allowed in 'netlist', others will be ignored." << endl;
@ -203,21 +207,21 @@ Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) {
xmlNode* child = node->children; xmlNode* child = node->children;
for (xmlNode* node = child; node; node = node->next) { for (xmlNode* node = child; node; node = node->next) {
if (node->type == XML_ELEMENT_NODE) { if (node->type == XML_ELEMENT_NODE) {
//if (xmlStrEqual(node->name, (xmlChar*)"connectors")) { if (xmlStrEqual(node->name, (xmlChar*)"connectors")) {
// readInstanceConnectors(node, inst); readInstanceConnectors(node, inst);
//} else } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) {
if (xmlStrEqual(node->name, (xmlChar*)"parameters")) {
readInstanceParameters(node, inst); readInstanceParameters(node, inst);
} else if (xmlStrEqual(node->name, (xmlChar*)"transistors")) {
readInstanceTransistors(node, inst);
} else { } else {
cerr << "[WARNING] Only 'parameters' node is allowed in 'instance', others will be ignored." << endl; //cerr << "[WARNING] Only 'parameters' node is allowed in 'instance', others will be ignored." << endl;
//cerr << "[WARNING] Only 'conectors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl;
} }
} }
} }
return inst; return inst;
} }
/*
void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) { void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) {
xmlNode* child = node->children; xmlNode* child = node->children;
for (xmlNode* node = child; node; node = node->next) { for (xmlNode* node = child; node; node = node->next) {
@ -230,7 +234,6 @@ void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) {
} }
} }
} }
*/
void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) { void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) {
xmlNode* child = node->children; xmlNode* child = node->children;
@ -253,7 +256,68 @@ void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) {
} }
} }
} }
void Circuit::readInstanceTransistors(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*)"transistor")) {
readTransistor(node, inst);
} else {
cerr << "[WARNING] Only 'transistor' nodes are allowed in 'transistors', others will be ignored." << endl;
}
}
}
}
void Circuit::readTransistor(xmlNode* node, Instance* inst) {
xmlChar* tNameC = xmlGetProp(node, (xmlChar*)"name");
Transistor* trans = NULL;
if (tNameC) {
Name tName((const char*)tNameC);
trans = new Transistor(tName, inst);
} else {
throw OpenChamsException("[ERROR] 'transistor' node must have 'name' property.");
//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*)"connection")) {
readTransistorConnection(node, trans);
} else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) {
cerr << "Transistor parameters NOT SUPPORTED YET" << endl;
} else {
cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl;
}
}
}
inst->addTransistor(trans);
}
void Circuit::readTransistorConnection(xmlNode* node, Transistor* trans) {
xmlChar* gateC = xmlGetProp(node, (xmlChar*)"gate");
xmlChar* sourceC = xmlGetProp(node, (xmlChar*)"source");
xmlChar* drainC = xmlGetProp(node, (xmlChar*)"drain");
xmlChar* bulkC = xmlGetProp(node, (xmlChar*)"bulk");
if (gateC && sourceC && drainC && bulkC) {
Name gateN ((const char*)gateC);
Name sourceN((const char*)sourceC);
Name drainN ((const char*)drainC);
Name bulkN ((const char*)bulkC);
trans->setGate(gateN);
trans->setSource(sourceN);
trans->setDrain(drainN);
trans->setBulk(bulkN);
} else {
throw OpenChamsException("[ERROR] 'connection' node must have 'gate', 'source', 'drain' and 'bulk' properties.");
}
}
// NETS //
void Circuit::readNets(xmlNode* node, Netlist* netlist) { void Circuit::readNets(xmlNode* node, Netlist* netlist) {
if (readNetsDone) { if (readNetsDone) {
cerr << "[WARNING] Only one 'nets' node is allowed in 'netlist', others will be ignored." << endl; cerr << "[WARNING] Only one 'nets' node is allowed in 'netlist', others will be ignored." << endl;
@ -331,7 +395,8 @@ void Circuit::readNetConnector(xmlNode* node, Net* net) {
throw OpenChamsException("[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)."); throw OpenChamsException("[ERROR] 'connector' node must have 'instance' and 'name' properties (for net).");
} }
} }
// SCHEMATIC //
void Circuit::readSchematic(xmlNode* node) { void Circuit::readSchematic(xmlNode* node) {
if (readSchematicDone) { if (readSchematicDone) {
cerr << "[WARNING] Only one 'schematic' node is allowed in circuit, others will be ignored." << endl; cerr << "[WARNING] Only one 'schematic' node is allowed in circuit, others will be ignored." << endl;
@ -379,6 +444,7 @@ void Circuit::readInstanceSchematic(xmlNode* node, Schematic* schematic) {
} }
} }
// SIZING //
void Circuit::readSizing(xmlNode* node) { void Circuit::readSizing(xmlNode* node) {
if (readSizingDone) { if (readSizingDone) {
cerr << "[WARNING] Only one 'sizing' node is allowed in circuit, others will be ignored." << endl; cerr << "[WARNING] Only one 'sizing' node is allowed in circuit, others will be ignored." << endl;
@ -459,6 +525,7 @@ void Circuit::readConstraint(xmlNode* node, Operator* op) {
throw OpenChamsException("[ERROR] 'constraint' node must have 'param, ref, refParam, [factor]' or 'param, refEq, [factor]' properties."); throw OpenChamsException("[ERROR] 'constraint' node must have 'param, ref, refParam, [factor]' or 'param, refEq, [factor]' properties.");
} }
} }
void Circuit::readEquations(xmlNode* node, Sizing* sizing) { void Circuit::readEquations(xmlNode* node, Sizing* sizing) {
xmlNode* child = node->children; xmlNode* child = node->children;
for (xmlNode* node = child; node; node = node->next) { for (xmlNode* node = child; node; node = node->next) {
@ -569,20 +636,34 @@ bool Circuit::writeToFile(string filePath) {
<< " <instances>" << endl; << " <instances>" << endl;
for (vector<Instance*>::const_iterator it = _netlist->getInstances().begin() ; it != _netlist->getInstances().end() ; ++it) { for (vector<Instance*>::const_iterator it = _netlist->getInstances().begin() ; it != _netlist->getInstances().end() ; ++it) {
Instance* inst = (*it); Instance* inst = (*it);
/*if (inst->hasNoConnectors()) { if (inst->hasNoConnectors()) {
string error("[ERROR] Cannot writeToFile since instance ("); string error("[ERROR] Cannot writeToFile since instance (");
error += inst->getName().getString(); error += inst->getName().getString();
error += ") has no connectors !"; error += ") has no connectors !";
throw OpenChamsException(error); throw OpenChamsException(error);
//return false; //return false;
}*/ }
if (inst->hasNoTransistors()) {
string error("[ERROR] Cannot writeToFile since instance (");
error += inst->getName().getString();
error += ") has no transistors !";
throw OpenChamsException(error);
}
string sourceBulkStr = (inst->isSourceBulkConnected()) ? "True" : "False"; string sourceBulkStr = (inst->isSourceBulkConnected()) ? "True" : "False";
file << " <instance name=\"" << inst->getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\">" << endl; file << " <instance name=\"" << inst->getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\">" << endl;
/*file << " <connectors>" << endl; file << " <connectors>" << endl;
for (map<Name, Net*>::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { for (map<Name, Net*>::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) {
file << " <connector name=\"" << (*it).first.getString() << "\"/>" << endl; file << " <connector name=\"" << (*it).first.getString() << "\"/>" << endl;
} }
file << " </connectors>" << endl;*/ file << " </connectors>" << endl
<< " <transistors>" << endl;
for (vector<Transistor*>::const_iterator it = inst->getTransistors().begin() ; it != inst->getTransistors().end() ; ++it ) {
Transistor* tr = (*it);
file << " <transistor name=\"" << tr->getName().getString() << "\">" << endl
<< " <connection gate=\"" << tr->getGate().getString() << "\" source=\"" << tr->getSource().getString() << "\" drain=\"" << tr->getDrain().getString() << "\" bulk=\"" << tr->getBulk().getString() << "\"/>" << endl
<< " </transistor>" << endl;
}
file << " </transistors>" << endl;
if (!inst->getParameters().isEmpty()) { if (!inst->getParameters().isEmpty()) {
Parameters params = inst->getParameters(); Parameters params = inst->getParameters();
file << " <parameters>" << endl; file << " <parameters>" << endl;

View File

@ -22,6 +22,7 @@
#include "Net.h" #include "Net.h"
#include "Schematic.h" #include "Schematic.h"
#include "Sizing.h" #include "Sizing.h"
#include "Transistor.h"
#include "Operator.h" #include "Operator.h"
namespace OpenChams { namespace OpenChams {
@ -54,7 +55,10 @@ class Circuit {
void readInstances(xmlNode*, Netlist*); void readInstances(xmlNode*, Netlist*);
Instance* readInstance (xmlNode*, Netlist*); Instance* readInstance (xmlNode*, Netlist*);
void readInstanceParameters(xmlNode*, Instance*); void readInstanceParameters(xmlNode*, Instance*);
//void readInstanceConnectors(xmlNode*, Instance*); void readInstanceConnectors(xmlNode*, Instance*);
void readInstanceTransistors(xmlNode*, Instance*);
void readTransistor(xmlNode*, Instance*);
void readTransistorConnection(xmlNode*, Transistor*);
void readNets(xmlNode*, Netlist*); void readNets(xmlNode*, Netlist*);
Net* readNet (xmlNode*, Netlist*); Net* readNet (xmlNode*, Netlist*);
void readNetConnector(xmlNode*, Net*); void readNetConnector(xmlNode*, Net*);

View File

@ -13,6 +13,7 @@ using namespace std;
#include "Instance.h" #include "Instance.h"
#include "Netlist.h" #include "Netlist.h"
#include "Net.h" #include "Net.h"
#include "Transistor.h"
#include "OpenChamsException.h" #include "OpenChamsException.h"
namespace OpenChams { namespace OpenChams {

View File

@ -11,6 +11,7 @@
#define __OPENCHAMS_INSTANCE_H__ #define __OPENCHAMS_INSTANCE_H__
#include <map> #include <map>
#include <vector>
#include "Name.h" #include "Name.h"
#include "Parameters.h" #include "Parameters.h"
@ -18,6 +19,7 @@
namespace OpenChams { namespace OpenChams {
class Netlist; class Netlist;
class Net; class Net;
class Transistor;
class Instance { class Instance {
public: public:
Instance(Name name, Name model, Name mosType, bool, Netlist*); Instance(Name name, Name model, Name mosType, bool, Netlist*);
@ -29,6 +31,7 @@ class Instance {
inline void addParameter(Name, double); inline void addParameter(Name, double);
inline void addParameter(Name, std::string); inline void addParameter(Name, std::string);
inline void addTransistor(Transistor*);
inline Name getName(); inline Name getName();
inline Name getModel(); inline Name getModel();
inline Name getMosType(); inline Name getMosType();
@ -36,9 +39,10 @@ class Instance {
inline Parameters getParameters(); inline Parameters getParameters();
// pour parcourir les connecteurs // pour parcourir les connecteurs
inline bool hasNoConnectors(); inline bool hasNoConnectors();
//inline map<Name, Net*>::iterator getFirstConnectorIt();
//inline map<Name, Net*>::iterator getLastConnectorIt();
inline const std::map<Name, Net*>& getConnectors(); inline const std::map<Name, Net*>& getConnectors();
// pour parcourir les transistors
inline bool hasNoTransistors();
inline const std::vector<Transistor*>& getTransistors();
private: private:
Name _name; Name _name;
@ -47,20 +51,22 @@ class Instance {
bool _sourceBulkConnected; bool _sourceBulkConnected;
Netlist* _netlist; Netlist* _netlist;
Parameters _params; Parameters _params;
std::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
std::vector<Transistor*> _trans;
}; };
inline void Instance::addParameter(Name name, double value) { _params.addParameter(name, value); }; 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::addParameter(Name name, std::string eqStr) { _params.addParameter(name, eqStr); };
inline void Instance::addTransistor(Transistor* tr) { _trans.push_back(tr); };
inline Name Instance::getName() { return _name; }; inline Name Instance::getName() { return _name; };
inline Name Instance::getModel() { return _model; }; inline Name Instance::getModel() { return _model; };
inline Name Instance::getMosType() { return _mosType; }; inline Name Instance::getMosType() { return _mosType; };
inline bool Instance::isSourceBulkConnected() { return _sourceBulkConnected; }; inline bool Instance::isSourceBulkConnected() { return _sourceBulkConnected; };
inline Parameters Instance::getParameters() { return _params; }; inline Parameters Instance::getParameters() { return _params; };
inline bool Instance::hasNoConnectors() { return (_netMap.size() == 0)? true : false; }; 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 const std::map<Name, Net*>& Instance::getConnectors() { return _netMap; }; inline const std::map<Name, Net*>& Instance::getConnectors() { return _netMap; };
inline bool Instance::hasNoTransistors() { return (_trans.size() == 0)? true : false; };
inline const std::vector<Transistor*>& Instance::getTransistors() { return _trans; };
} // namespace } // namespace
#endif #endif

View File

@ -0,0 +1,61 @@
/*
* Transistor.cpp
* openChams
*
* Created by damien dupuis on 01/03/10.
* Copyright 2010 UPMC / LIP6. All rights reserved.
*
*/
#include <iostream>
using namespace std;
#include "Transistor.h"
#include "Instance.h"
#include "Net.h"
#include "OpenChamsException.h"
namespace OpenChams {
Transistor::Transistor(Name name, Instance* instance)
: _name(name)
, _gate("")
, _source("")
, _drain("")
, _bulk("")
, _instance(instance) {}
void Transistor::setGate(Name gate) {
if (checkConnector(gate))
_gate = gate;
}
void Transistor::setSource(Name source) {
if (checkConnector(source))
_source = source;
}
void Transistor::setDrain(Name drain) {
if (checkConnector(drain))
_drain = drain;
}
void Transistor::setBulk(Name bulk) {
if (checkConnector(bulk))
_bulk = bulk;
}
bool Transistor::checkConnector(Name name) {
map<Name, Net*>::const_iterator it = _instance->getConnectors().find(name);
if (it != _instance->getConnectors().end()) {// si le connecteur existe bien
return true;
} else {
string error("[ERROR] Instance ");
error += _instance->getName().getString();
error += " has no connector named ";
error += name.getString();
error += ".";
throw OpenChamsException(error);
}
}
}

View File

@ -0,0 +1,64 @@
/*
* Transistor.h
* openChams
*
* Created by damien dupuis on 01/03/10.
* Copyright 2010 UPMC / LIP6. All rights reserved.
*
*/
#ifndef __OPENCHAMS_TRANSISTOR_H__
#define __OPENCHAMS_TRANSISTOR_H__
#include <map>
#include "Name.h"
#include "Parameters.h"
namespace OpenChams {
class Instance;
class Net;
class Transistor {
public:
Transistor(Name, Instance*);
inline void addParameter(Name, double);
inline void addParameter(Name, std::string);
inline Parameters getParameters();
inline void setName(Name);
inline Name getName();
inline Name getGate();
inline Name getSource();
inline Name getDrain();
inline Name getBulk();
void setGate (Name);
void setSource(Name);
void setDrain (Name);
void setBulk (Name);
private:
bool checkConnector(Name);
Name _name;
Name _gate; // le nom du connecteur de _instance auquel la gate est reliée
Name _source; // le nom du connecteur de _instance auquel la source est reliée
Name _drain; // le nom du connecteur de _instance auquel le drain est relié
Name _bulk; // le nom du connecteur de _instance auquel le bulk est relié
Instance* _instance;
Parameters _params;
};
inline void Transistor::addParameter(Name name, double value) { _params.addParameter(name, value); };
inline void Transistor::addParameter(Name name, std::string eqStr) { _params.addParameter(name, eqStr); };
inline Parameters Transistor::getParameters() { return _params; };
inline void Transistor::setName (Name name) { _name = name; };
inline Name Transistor::getName() { return _name; };
inline Name Transistor::getGate() { return _gate; };
inline Name Transistor::getSource() { return _source; };
inline Name Transistor::getDrain() { return _drain; };
inline Name Transistor::getBulk() { return _bulk; };
} // namespace
#endif