diff --git a/vlsisapd/src/openChams/src/CMakeLists.txt b/vlsisapd/src/openChams/src/CMakeLists.txt index db8d275f..6d67dde6 100644 --- a/vlsisapd/src/openChams/src/CMakeLists.txt +++ b/vlsisapd/src/openChams/src/CMakeLists.txt @@ -10,6 +10,7 @@ SET ( hpps vlsisapd/openChams/Circuit.h vlsisapd/openChams/Schematic.h vlsisapd/openChams/SimulModel.h vlsisapd/openChams/Sizing.h + vlsisapd/openChams/Layout.h vlsisapd/openChams/Transistor.h vlsisapd/openChams/OpenChamsException.h ) @@ -23,6 +24,7 @@ SET ( cpps Circuit.cpp Schematic.cpp SimulModel.cpp Sizing.cpp + Layout.cpp Transistor.cpp ) SET ( pycpps PyOpenChams.cpp diff --git a/vlsisapd/src/openChams/src/Circuit.cpp b/vlsisapd/src/openChams/src/Circuit.cpp index 68ad2cb9..4b99ccce 100644 --- a/vlsisapd/src/openChams/src/Circuit.cpp +++ b/vlsisapd/src/openChams/src/Circuit.cpp @@ -21,6 +21,7 @@ using namespace std; #include "vlsisapd/openChams/Schematic.h" #include "vlsisapd/openChams/SimulModel.h" #include "vlsisapd/openChams/Sizing.h" +#include "vlsisapd/openChams/Layout.h" #include "vlsisapd/openChams/Transistor.h" #include "vlsisapd/openChams/Operator.h" #include "vlsisapd/openChams/OpenChamsException.h" @@ -44,8 +45,9 @@ static bool readInstancesDone = false; static bool readNetsDone = false; static bool readSchematicDone = false; static bool readSizingDone = false; +static bool readLayoutDone = false; -Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL) { +Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL), _layout(NULL) { readCircuitParametersDone = false; readSimulModelsDone = false; readNetListDone = false; @@ -53,6 +55,7 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis readNetsDone = false; readSchematicDone = false; readSizingDone = false; + readLayoutDone = false; } // COMPARISON FUNCTION // @@ -641,6 +644,40 @@ void Circuit::readEquation(xmlNode* node, Sizing* sizing) { } } +// LAYOUT // +void Circuit::readLayout(xmlNode* node) { + if (readLayoutDone) { + cerr << "[WARNING] Only one 'layout' node is allowed in circuit, others will be ignored." << endl; + return; + } + + Layout* layout = new Layout(this); + xmlNode* child = node->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstanceLayout(node, layout); + } else { + cerr << "[WARNING] Only 'instance' nodes are allowed in 'sizing', others will be ignored." << endl; + } + } + } + readLayoutDone = true; + _layout = layout; +} + +void Circuit::readInstanceLayout(xmlNode* node, Layout* layout) { + xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); + xmlChar* styleC = xmlGetProp(node, (xmlChar*)"style"); + if (nameC && styleC) { + Name iName ((const char*)nameC); + Name styleName ((const char*)styleC); + layout->addInstance(iName, styleName); + } else { + throw OpenChamsException("[ERROR] 'instance' node in 'layout' must have 'name' and 'style' properties."); + } +} + Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; Circuit* cir = NULL; @@ -684,6 +721,9 @@ Circuit* Circuit::readFromFile(const string filePath) { else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { cir->readSizing(node); } + else if (xmlStrEqual(node->name, (xmlChar*)"layout")) { + cir->readLayout(node); + } else { string error("[ERROR] Unknown section "); error += string((const char*)node->name); @@ -733,6 +773,17 @@ Sizing* Circuit::createSizing() { return _sizing; } +Layout* Circuit::createLayout() { + if (_layout) + throw OpenChamsException("[ERROR] Cannot create two layouts in one circuit."); + + _layout = new Layout(this); + if (!_layout) + throw OpenChamsException("[ERROR] Cannot create layout."); + + return _layout; +} + bool Circuit::writeToFile(string filePath) { ofstream file; file.open(filePath.c_str()); @@ -874,6 +925,13 @@ bool Circuit::writeToFile(string filePath) { } file << " " << endl; } + if (_layout && !_layout->hasNoInstance()) { + file << " " << endl; + for (map::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) { + file << " " << endl; + } + file << " " << endl; + } file << "" << endl; file.close(); return true; diff --git a/vlsisapd/src/openChams/src/Layout.cpp b/vlsisapd/src/openChams/src/Layout.cpp new file mode 100644 index 00000000..e478eb26 --- /dev/null +++ b/vlsisapd/src/openChams/src/Layout.cpp @@ -0,0 +1,32 @@ +/* + * Layout.cpp + * openChams + * + * Created by damien dupuis on 31/08/10. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#include +using namespace std; + +#include "vlsisapd/openChams/Layout.h" +#include "vlsisapd/openChams/Circuit.h" +#include "vlsisapd/openChams/OpenChamsException.h" + +namespace OpenChams { +Layout::Layout(Circuit* circuit): _circuit(circuit) {} + +void Layout::addInstance(Name name, Name style) { + map::iterator it = _instances.find(name); + if (it != _instances.end()) { + string error("[ERROR] Cannot set several instances with the same name in 'layout' ("); + error += name.getString(); + error += ")."; + throw OpenChamsException(error); + } + _instances[name] = style; +} + +} // namespace + diff --git a/vlsisapd/src/openChams/src/PyOpenChams.cpp b/vlsisapd/src/openChams/src/PyOpenChams.cpp index c559cc16..9a05a3cc 100644 --- a/vlsisapd/src/openChams/src/PyOpenChams.cpp +++ b/vlsisapd/src/openChams/src/PyOpenChams.cpp @@ -14,6 +14,7 @@ using namespace boost::python; #include "vlsisapd/openChams/Operator.h" #include "vlsisapd/openChams/SimulModel.h" #include "vlsisapd/openChams/Sizing.h" +#include "vlsisapd/openChams/Layout.h" #include "vlsisapd/openChams/Circuit.h" #include "vlsisapd/openChams/OpenChamsException.h" @@ -238,6 +239,18 @@ BOOST_PYTHON_MODULE(OPENCHAMS) { .def("getOperators", &Sizing::getOperators, return_internal_reference<>()) ; + // map wrapping for OpenChams::Layout + STL_MAP_WRAPPING(Name, Name, "LayoutInstancesMap") + // class OpenChams::Layout + class_("Layout", init()) + // accessors + .def("hasNoInstance", &Layout::hasNoInstance) + // modifiers + .def("addInstance", &Layout::addInstance) + // stl containers + .def("getInstances", &Layout::getInstances, return_internal_reference<>()) + ; + class_("Circuit", init()) // properties .add_property("name" , &Circuit::getName ) @@ -246,12 +259,14 @@ BOOST_PYTHON_MODULE(OPENCHAMS) { .add_property("netlist" , make_function(&Circuit::getNetlist , return_value_policy())) .add_property("schematic" , make_function(&Circuit::getSchematic, return_value_policy())) .add_property("sizing" , make_function(&Circuit::getSizing , return_value_policy())) + .add_property("layout" , make_function(&Circuit::getLayout , return_value_policy())) // accessors .def("getValue", &Circuit::getValue) // modifiers .def("createNetlist" , &Circuit::createNetlist , return_value_policy()) .def("createSchematic", &Circuit::createSchematic, return_value_policy()) .def("createSizing" , &Circuit::createSizing , return_value_policy()) + .def("createLayout" , &Circuit::createLayout , return_value_policy()) .def("addParameter", static_cast(&Circuit::addParameter)) .def("addParameter", static_cast(&Circuit::addParameter)) // others diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h index 4eeb4dfb..a024f6b6 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h @@ -28,6 +28,7 @@ class Schematic; class Sizing; class Transistor; class Operator; +class Layout; class Circuit { public: @@ -39,6 +40,7 @@ class Circuit { inline Netlist* getNetlist(); inline Schematic* getSchematic(); inline Sizing* getSizing(); + inline Layout* getLayout(); inline void addParameter(Name, double); inline void addParameter(Name, std::string); inline Parameters getParameters(); @@ -46,10 +48,12 @@ class Circuit { void addSimulModel(unsigned, SimulModel::Base, SimulModel::Version, std::string); inline void setSizing(Sizing*); + inline void setLayout(Layout*); Netlist* createNetlist(); Schematic* createSchematic(double); Sizing* createSizing(); + Layout* createLayout(); bool writeToFile(std::string filePath); static Circuit* readFromFile(const std::string filePath); @@ -78,6 +82,8 @@ class Circuit { void readConstraint(xmlNode*, Operator*); void readEquations(xmlNode*, Sizing*); void readEquation(xmlNode*, Sizing*); + void readLayout(xmlNode*); + void readInstanceLayout(xmlNode*, Layout*); void check_uppercase(std::string& str, std::vector& compares, std::string message); void check_lowercase(std::string& str, std::vector& compares, std::string message); @@ -88,6 +94,7 @@ class Circuit { Netlist* _netlist; Schematic* _schematic; Sizing* _sizing; + Layout* _layout; std::map _simulModels; }; @@ -97,6 +104,7 @@ inline double Circuit::getValue(Name name) { return _params.getValue(name); inline Netlist* Circuit::getNetlist() { return _netlist; }; inline Schematic* Circuit::getSchematic() { return _schematic; }; inline Sizing* Circuit::getSizing() { return _sizing; }; +inline Layout* Circuit::getLayout() { return _layout; }; 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; }; diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h new file mode 100644 index 00000000..e6e167e2 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h @@ -0,0 +1,37 @@ +/* + * Layout.h + * openChams + * + * Created by damien dupuis on 31/08/10. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_LAYOUT_H__ +#define __OPENCHAMS_LAYOUT_H__ + +#include + +namespace OpenChams { +class Name; +class Circuit; + +class Layout { + public: + Layout(Circuit*); + + void addInstance(Name name, Name style); + + inline bool hasNoInstance(); + inline const std::map& getInstances(); + + private: + Circuit* _circuit; + std::map _instances; // device name <-> style (name) + }; + + inline bool Layout::hasNoInstance() { return (_instances.size() == 0) ? true : false; }; + inline const std::map& Layout::getInstances() { return _instances; }; +} // namespace +#endif + diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Parameters.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Parameters.h index 5882f5ba..6c47841b 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Parameters.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Parameters.h @@ -3,7 +3,7 @@ * openChams * * Created by damien dupuis on 18/12/09. - * Copyright 2009 UPMC / LIP6. All rights reserved. + * Copyright 2008-2010 UPMC / LIP6. All rights reserved. * */ diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h index 34e7f917..2ad1a1f0 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Schematic.h @@ -1,5 +1,5 @@ /* - * SchematicInfos.h + * Schematic.h * openChams * * Created by damien dupuis on 22/01/10.