From feef029cae352347be5ef645353b9a8c716e3951 Mon Sep 17 00:00:00 2001 From: Damien Dupuis Date: Tue, 2 Mar 2010 13:25:31 +0000 Subject: [PATCH] Added support to transistor in instance so we can reach transistor level in netlist. --- vlsisapd/openChams/CMakeLists.txt | 25 ++++++- vlsisapd/openChams/Circuit.cpp | 111 ++++++++++++++++++++++++++---- vlsisapd/openChams/Circuit.h | 6 +- vlsisapd/openChams/Instance.cpp | 1 + vlsisapd/openChams/Instance.h | 16 +++-- vlsisapd/openChams/Transistor.cpp | 61 ++++++++++++++++ vlsisapd/openChams/Transistor.h | 64 +++++++++++++++++ 7 files changed, 261 insertions(+), 23 deletions(-) create mode 100644 vlsisapd/openChams/Transistor.cpp create mode 100644 vlsisapd/openChams/Transistor.h diff --git a/vlsisapd/openChams/CMakeLists.txt b/vlsisapd/openChams/CMakeLists.txt index 5760edbd..148e9e6b 100644 --- a/vlsisapd/openChams/CMakeLists.txt +++ b/vlsisapd/openChams/CMakeLists.txt @@ -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}) diff --git a/vlsisapd/openChams/Circuit.cpp b/vlsisapd/openChams/Circuit.cpp index f028bc5a..fbd68c14 100644 --- a/vlsisapd/openChams/Circuit.cpp +++ b/vlsisapd/openChams/Circuit.cpp @@ -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& 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) { << " " << endl; for (vector::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 << " getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\">" << endl; - /*file << " " << endl; + file << " " << endl; for (map::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { file << " " << endl; } - file << " " << endl;*/ + file << " " << endl + << " " << endl; + for (vector::const_iterator it = inst->getTransistors().begin() ; it != inst->getTransistors().end() ; ++it ) { + Transistor* tr = (*it); + file << " getName().getString() << "\">" << endl + << " getGate().getString() << "\" source=\"" << tr->getSource().getString() << "\" drain=\"" << tr->getDrain().getString() << "\" bulk=\"" << tr->getBulk().getString() << "\"/>" << endl + << " " << endl; + } + file << " " << endl; if (!inst->getParameters().isEmpty()) { Parameters params = inst->getParameters(); file << " " << endl; diff --git a/vlsisapd/openChams/Circuit.h b/vlsisapd/openChams/Circuit.h index 4ed18ba5..01c1da4b 100644 --- a/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/openChams/Circuit.h @@ -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*); diff --git a/vlsisapd/openChams/Instance.cpp b/vlsisapd/openChams/Instance.cpp index 4626388c..0b53b396 100644 --- a/vlsisapd/openChams/Instance.cpp +++ b/vlsisapd/openChams/Instance.cpp @@ -13,6 +13,7 @@ using namespace std; #include "Instance.h" #include "Netlist.h" #include "Net.h" +#include "Transistor.h" #include "OpenChamsException.h" namespace OpenChams { diff --git a/vlsisapd/openChams/Instance.h b/vlsisapd/openChams/Instance.h index f599f318..cc256822 100644 --- a/vlsisapd/openChams/Instance.h +++ b/vlsisapd/openChams/Instance.h @@ -11,6 +11,7 @@ #define __OPENCHAMS_INSTANCE_H__ #include +#include #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::iterator getFirstConnectorIt(); - //inline map::iterator getLastConnectorIt(); inline const std::map& getConnectors(); + // pour parcourir les transistors + inline bool hasNoTransistors(); + inline const std::vector& getTransistors(); private: Name _name; @@ -47,20 +51,22 @@ class Instance { bool _sourceBulkConnected; Netlist* _netlist; Parameters _params; - std::map _netMap; //map associant nom de connecteur a un net + std::map _netMap; //map associant nom de connecteur a un net + std::vector _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::iterator Instance::getFirstConnectorIt() { return _netMap.begin(); }; -//inline map::iterator Instance::getLastConnectorIt() { return _netMap.end(); }; inline const std::map& Instance::getConnectors() { return _netMap; }; +inline bool Instance::hasNoTransistors() { return (_trans.size() == 0)? true : false; }; +inline const std::vector& Instance::getTransistors() { return _trans; }; } // namespace #endif diff --git a/vlsisapd/openChams/Transistor.cpp b/vlsisapd/openChams/Transistor.cpp new file mode 100644 index 00000000..ae5663ba --- /dev/null +++ b/vlsisapd/openChams/Transistor.cpp @@ -0,0 +1,61 @@ +/* + * Transistor.cpp + * openChams + * + * Created by damien dupuis on 01/03/10. + * Copyright 2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +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::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); + } + } +} + + diff --git a/vlsisapd/openChams/Transistor.h b/vlsisapd/openChams/Transistor.h new file mode 100644 index 00000000..bf7ddd09 --- /dev/null +++ b/vlsisapd/openChams/Transistor.h @@ -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 + +#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 +