From 6476d1492cc48108744ce9ea5d021af6df7f94d3 Mon Sep 17 00:00:00 2001 From: Damien Dupuis Date: Tue, 10 May 2011 11:09:56 +0000 Subject: [PATCH] Several changes to correctly parse & drive current spice example. --- vlsisapd/src/spice/src/CMakeLists.txt | 1 + vlsisapd/src/spice/src/Circuit.cpp | 54 +++++++++++++++---- vlsisapd/src/spice/src/Subckt.cpp | 16 ++++++ .../src/spice/src/vlsisapd/spice/Subckt.h | 26 +++++---- 4 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 vlsisapd/src/spice/src/Subckt.cpp diff --git a/vlsisapd/src/spice/src/CMakeLists.txt b/vlsisapd/src/spice/src/CMakeLists.txt index 8d4b3bac..89f88910 100644 --- a/vlsisapd/src/spice/src/CMakeLists.txt +++ b/vlsisapd/src/spice/src/CMakeLists.txt @@ -10,6 +10,7 @@ SET ( hpps vlsisapd/spice/Circuit.h ) SET ( cpps Circuit.cpp Instance.cpp + Subckt.cpp Value.cpp ) #SET ( pycpps PySpice.cpp diff --git a/vlsisapd/src/spice/src/Circuit.cpp b/vlsisapd/src/spice/src/Circuit.cpp index 27ad35c8..01138a1c 100644 --- a/vlsisapd/src/spice/src/Circuit.cpp +++ b/vlsisapd/src/spice/src/Circuit.cpp @@ -13,7 +13,7 @@ using namespace std; #include "vlsisapd/spice/SpiceException.h" namespace SPICE { -#define DEBUG +//#define DEBUG void Circuit::addOption(string name, string value) { map::iterator it = _options.find(name); if (it != _options.end()) { @@ -120,8 +120,17 @@ Circuit* Circuit::readFromFile(const string& filename) { if (inSubckt) throw SpiceException("SPICE::Circuit::readFromFile: Found hierarchic .subckt !"); inSubckt = true; sub = circuit->addSubckt(tokens[1]); - for (size_t i = 2 ; i < tokens.size() ; i++) + size_t paramTok = tokens.size(); + for (size_t i = 2 ; i < tokens.size() ; i++) + if ((tokens[i] == "param:") || (tokens[i] == "PARAM:")) + paramTok = i; + for (size_t i = 2 ; i < paramTok ; i++) sub->addInterface(tokens[i]); + for (size_t i = paramTok+1 ; i < tokens.size() ; i++) { + string name, value; + parametrize(tokens[i], name, value); + sub->addParameter(name, value); + } break; } case Circuit::ENDSUB: @@ -148,7 +157,7 @@ Circuit* Circuit::readFromFile(const string& filename) { break; } } - Instance* inst = new Instance(tokens[0], tokens[modelIdx]); + Instance* inst = new Instance(tokens[0].erase(0,1), tokens[modelIdx]); for (size_t i = 1 ; i < modelIdx ; i++) inst->addConnector(tokens[i]); for (size_t i = modelIdx+1 ; i < tokens.size() ; i++) { @@ -181,6 +190,18 @@ Circuit* Circuit::readFromFile(const string& filename) { #ifdef DEBUG cerr << "MOSFET | " << line << endl; #endif + // name drain grid source bulk model + Mosfet* mos = new Mosfet(tokens[0].erase(0,1), tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]); + for (size_t i = 6 ; i < tokens.size() ; i++) { + string name, value; + parametrize(tokens[i], name, value); + mos->addParameter(name, value); + } + if (inSubckt) { // must add mosfet to current subckt + sub->addInstance(mos); + } else { // instance is mosfet to top-level circuit + circuit->addInstance(mos); + } break; } case Circuit::CAPACITOR: @@ -188,7 +209,7 @@ Circuit* Circuit::readFromFile(const string& filename) { #ifdef DEBUG cerr << "CAPACITOR| " << line << endl; #endif - Instance* inst = new Capacitor(tokens[0], tokens[1], tokens[2], tokens[3]); + Instance* inst = new Capacitor(tokens[0].erase(0,1), tokens[1], tokens[2], tokens[3]); if (inSubckt) { // must add instance to current subckt sub->addInstance(inst); } else { // instance is added to top-level circuit @@ -201,7 +222,7 @@ Circuit* Circuit::readFromFile(const string& filename) { #ifdef DEBUG cerr << "RESISTOR | " << line << endl; #endif - Instance* inst = new Resistor(tokens[0], tokens[1], tokens[2], tokens[3]); + Instance* inst = new Resistor(tokens[0].erase(0,1), tokens[1], tokens[2], tokens[3]); if (inSubckt) { // must add instance to current subckt sub->addInstance(inst); } else { // instance is added to top-level circuit @@ -289,6 +310,11 @@ void Circuit::writeToFile(const string& filename) { spfile << ".SUBCKT " << sub->getName(); for (size_t j = 0 ; j < sub->getInterfaces().size() ; j++) spfile << " " << sub->getInterfaces()[j]; + if (sub->getParameters().size()) { + spfile << " PARAM:"; + for(map::const_iterator it = sub->getParameters().begin() ; it != sub->getParameters().end() ; ++it) + spfile << " " << (*it).first << "=" << (*it).second; + } spfile << endl; for (size_t j = 0 ; j < sub->getInstances().size() ; j++) { Instance* inst = sub->getInstances()[j]; @@ -406,19 +432,29 @@ void Circuit::parametrize(string param, string& name, string& value) { name = param.substr(0, it); value = param.substr(it+1, param.size()-it); } + #ifdef DEBUG cerr << "parametrize: " << name << "=" << value << endl; + #endif } void Circuit::writeInstance(std::ofstream& file, Instance* inst) { if (dynamic_cast(inst)) { + Mosfet* mos = static_cast(inst); + file << "M" << mos->getName() << " " << mos->getDrain() << " " << mos->getGrid() << " " << mos->getSource() << " " << mos->getBulk() << " " << mos->getModel(); + int j = 0; + for (map::const_iterator it =mos->getParameters().begin() ; it != mos->getParameters().end(); ++it, j++) { + if (j%6 == 0) + file << endl << "+"; + file << " " << (*it).first << "=" << (*it).second; + } } else if (dynamic_cast(inst)) { Capacitor* capa = static_cast(inst); - file << capa->getName() << " " << capa->getPositive() << " " << capa->getNegative() << " " << capa->getValue(); + file << "C" << capa->getName() << " " << capa->getPositive() << " " << capa->getNegative() << " " << capa->getValue(); } else if (dynamic_cast(inst)) { Resistor* res = static_cast(inst); - file << res->getName() << " " << res->getFirst() << " " << res->getSecond() << " " << res->getValue(); + file << "R" << res->getName() << " " << res->getFirst() << " " << res->getSecond() << " " << res->getValue(); } else { - file << inst->getName(); + file << "X" << inst->getName(); for (vector::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { file << " " << (*it); } @@ -430,6 +466,6 @@ void Circuit::writeInstance(std::ofstream& file, Instance* inst) { file << " " << (*it).first << "=" << (*it).second; } } - file << endl << endl; // to separate to consecutive instances + file << endl; } } diff --git a/vlsisapd/src/spice/src/Subckt.cpp b/vlsisapd/src/spice/src/Subckt.cpp new file mode 100644 index 00000000..00c5f6bd --- /dev/null +++ b/vlsisapd/src/spice/src/Subckt.cpp @@ -0,0 +1,16 @@ +#include +using namespace std; + +#include "vlsisapd/spice/Subckt.h" + +namespace SPICE { +void Subckt::addParameter(string name, string value) { + map::iterator pit = _parameters.find(name); + if (pit != _parameters.end()) { + cerr << "[WARNING] SPICE:: Cannot add parameter " << name + << " to subckt " << _name << " since it already exists." << endl; + return; + } + _parameters[name] = value; +} +} diff --git a/vlsisapd/src/spice/src/vlsisapd/spice/Subckt.h b/vlsisapd/src/spice/src/vlsisapd/spice/Subckt.h index d23d0c41..66830a10 100644 --- a/vlsisapd/src/spice/src/vlsisapd/spice/Subckt.h +++ b/vlsisapd/src/spice/src/vlsisapd/spice/Subckt.h @@ -4,30 +4,36 @@ #include #include +#include namespace SPICE { class Instance; class Subckt { private: - std::string _name; - std::vector _interfaces; - std::vector _instances; + std::string _name; + std::vector _interfaces; + std::vector _instances; + std::map _parameters; public: - Subckt(std::string name): _name(name), _interfaces(), _instances() {} + Subckt(std::string name): _name(name), _interfaces(), _instances(), _parameters() {} ~Subckt() {} - inline std::string getName(); - inline std::vector& getInterfaces(); - inline std::vector& getInstances(); + inline std::string getName(); + inline std::vector& getInterfaces(); + inline std::vector& getInstances(); + inline std::map& getParameters(); inline void addInterface(std::string); inline void addInstance (Instance*); + + void addParameter(std::string, std::string); }; -inline std::string Subckt::getName() { return _name; } -inline std::vector& Subckt::getInterfaces() { return _interfaces; } -inline std::vector& Subckt::getInstances() { return _instances; } +inline std::string Subckt::getName() { return _name; } +inline std::vector& Subckt::getInterfaces() { return _interfaces; } +inline std::vector& Subckt::getInstances() { return _instances; } +inline std::map& Subckt::getParameters() { return _parameters; } inline void Subckt::addInterface(std::string name) { _interfaces.push_back(name); } inline void Subckt::addInstance(Instance* inst) { _instances.push_back(inst); }