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