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})
SET ( includes Circuit.h Netlist.h Instance.h Net.h Name.h Operator.h Parameters.h Schematic.h Sizing.h OpenChamsException.h )
SET ( cpps Circuit.cpp Netlist.cpp Instance.cpp Net.cpp Name.cpp Operator.cpp Parameters.cpp Schematic.cpp Sizing.cpp )
SET ( includes
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})

View File

@ -45,6 +45,7 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis
readSizingDone = false;
}
// USEFUL //
void Circuit::check_uppercase(string& str, vector<string>& compares, string message) {
transform(str.begin(), str.end(), str.begin(), ::toupper);
bool equal = false;
@ -105,7 +106,8 @@ Name Circuit::readConnector(xmlNode* node) {
//return Name("");
}
}
// CIRCUIT //
void Circuit::readCircuitParameters(xmlNode* node) {
if (readCircuitParametersDone) {
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;
}
// NETLIST //
void Circuit::readNetList(xmlNode* node) {
if (readNetListDone) {
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;
_netlist = netlist;
}
// INSTANCES //
void Circuit::readInstances(xmlNode* node, Netlist* netlist) {
if (readInstancesDone) {
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;
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")) {
if (xmlStrEqual(node->name, (xmlChar*)"connectors")) {
readInstanceConnectors(node, inst);
} else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) {
readInstanceParameters(node, inst);
} else if (xmlStrEqual(node->name, (xmlChar*)"transistors")) {
readInstanceTransistors(node, inst);
} else {
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 'parameters' node is 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;
}
/*
void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) {
xmlNode* child = node->children;
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) {
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) {
if (readNetsDone) {
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).");
}
}
// SCHEMATIC //
void Circuit::readSchematic(xmlNode* node) {
if (readSchematicDone) {
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) {
if (readSizingDone) {
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.");
}
}
void Circuit::readEquations(xmlNode* node, Sizing* sizing) {
xmlNode* child = node->children;
for (xmlNode* node = child; node; node = node->next) {
@ -569,20 +636,34 @@ bool Circuit::writeToFile(string filePath) {
<< " <instances>" << endl;
for (vector<Instance*>::const_iterator it = _netlist->getInstances().begin() ; it != _netlist->getInstances().end() ; ++it) {
Instance* inst = (*it);
/*if (inst->hasNoConnectors()) {
if (inst->hasNoConnectors()) {
string error("[ERROR] Cannot writeToFile since instance (");
error += inst->getName().getString();
error += ") has no connectors !";
throw OpenChamsException(error);
//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";
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) {
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()) {
Parameters params = inst->getParameters();
file << " <parameters>" << endl;

View File

@ -22,6 +22,7 @@
#include "Net.h"
#include "Schematic.h"
#include "Sizing.h"
#include "Transistor.h"
#include "Operator.h"
namespace OpenChams {
@ -54,7 +55,10 @@ class Circuit {
void readInstances(xmlNode*, Netlist*);
Instance* readInstance (xmlNode*, Netlist*);
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*);
Net* readNet (xmlNode*, Netlist*);
void readNetConnector(xmlNode*, Net*);

View File

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

View File

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