diff --git a/vlsisapd/examples/openChams/cplusplus/driveOpenChams.cpp b/vlsisapd/examples/openChams/cplusplus/driveOpenChams.cpp index f20ca11c..0bf1ef47 100644 --- a/vlsisapd/examples/openChams/cplusplus/driveOpenChams.cpp +++ b/vlsisapd/examples/openChams/cplusplus/driveOpenChams.cpp @@ -11,6 +11,7 @@ using namespace std; #include "vlsisapd/openChams/Sizing.h" #include "vlsisapd/openChams/Operator.h" #include "vlsisapd/openChams/Layout.h" +#include "vlsisapd/openChams/Node.h" #include "vlsisapd/openChams/Port.h" #include "vlsisapd/openChams/Wire.h" @@ -109,6 +110,14 @@ int main(int argc, char * argv[]) { OpenChams::Layout* layout = circuit->createLayout(); layout->addInstance(OpenChams::Name("pmos1"), OpenChams::Name("Common transistor")); layout->addInstance(OpenChams::Name("nmos1"), OpenChams::Name("Rotate transistor")); + // create hbtree + OpenChams::Group* g1 = new OpenChams::Group("g1"); // default position is NONE and default parent is NULL + g1->setAlign(OpenChams::Group::VERTICAL); + OpenChams::Bloc* b1 = new OpenChams::Bloc("nmos1", OpenChams::Node::NONE, g1); + g1->setRootNode(b1); // b1 is root node of group g1 + OpenChams::Bloc* b2 = new OpenChams::Bloc("pmos1", OpenChams::Node::TOP, b1); + b1->setTop(b2); // b2 is on top of b1 + layout->setHBTreeRoot(g1); // g1 is the root of the tree circuit->writeToFile("./myInverter.xml"); return 0; diff --git a/vlsisapd/examples/openChams/cplusplus/parseOpenChams.cpp b/vlsisapd/examples/openChams/cplusplus/parseOpenChams.cpp index 69fd5a5a..734f25c3 100644 --- a/vlsisapd/examples/openChams/cplusplus/parseOpenChams.cpp +++ b/vlsisapd/examples/openChams/cplusplus/parseOpenChams.cpp @@ -16,10 +16,57 @@ using namespace std; #include "vlsisapd/openChams/Sizing.h" #include "vlsisapd/openChams/Operator.h" #include "vlsisapd/openChams/Layout.h" +#include "vlsisapd/openChams/Node.h" #include "vlsisapd/openChams/Port.h" #include "vlsisapd/openChams/Wire.h" #include "vlsisapd/openChams/OpenChamsException.h" +void printHBTree(OpenChams::Node* node, unsigned indent) { + if (!node) return; // since we pass nnode->getRight and node-getTop without checking for NULL + for (unsigned i = 0 ; i < indent ; i++) { + cerr << " |"; + } + string pos = ""; + switch(node->getPosition()) { + case OpenChams::Node::TOP: + pos = "top"; + break; + case OpenChams::Node::RIGHT: + pos = "right"; + break; + default: + break; + } + OpenChams::Bloc* bloc = dynamic_cast(node); + if (bloc) { + cerr << " bloc: " << bloc->getName().getString() << " - " << pos << endl; + printHBTree(bloc->getTop() , indent+1); + printHBTree(bloc->getRight(), indent+1); + return; + } + OpenChams::Group* group = dynamic_cast(node); + if (group) { + string align = "none"; + switch(group->getAlign()) { + case OpenChams::Group::VERTICAL: + align = "vertical"; + break; + case OpenChams::Group::HORIZONTAL: + align = "horizontal"; + break; + default: + break; + } + cerr << " group: " << group->getName().getString() << " - " << pos << " - align: " << align << " - isolated: " << group->isIsolated() << " - paired: " << group->isPaired() << endl; + printHBTree(group->getRootNode(), indent+1); + printHBTree(group->getTop() , indent+1); + printHBTree(group->getRight() , indent+1); + return; + } + cerr << "[ERROR] printHBTree: node is nor a bloc nor a group !" << endl; + return; +} + int main(int argc, char * argv[]) { string file = ""; if (argc == 1) @@ -166,11 +213,18 @@ int main(int argc, char * argv[]) { } } OpenChams::Layout* layout = circuit->getLayout(); - if (layout && !layout->hasNoInstance()) { - cerr << " + layout" << endl; - for (map::const_iterator lit = layout->getInstances().begin() ; lit != layout->getInstances().end() ; ++lit) { - cerr << " | | instance name: " << ((*lit).first).getString() << " - style: " << ((*lit).second).getString() << endl; - } + if (layout) { + if (!layout->hasNoInstance()) { + cerr << " + layout" << endl; + for (map::const_iterator lit = layout->getInstances().begin() ; lit != layout->getInstances().end() ; ++lit) { + cerr << " | | instance name: " << ((*lit).first).getString() << " - style: " << ((*lit).second).getString() << endl; + } + } + OpenChams::Node* root = layout->getHBTreeRoot(); + if (root) { + cerr << " | + hbtree" << endl; + printHBTree(root, 2); + } } diff --git a/vlsisapd/examples/openChams/inverter.xml b/vlsisapd/examples/openChams/inverter.xml index 0c1d36ab..49247179 100644 --- a/vlsisapd/examples/openChams/inverter.xml +++ b/vlsisapd/examples/openChams/inverter.xml @@ -119,5 +119,12 @@ + + + + + + + diff --git a/vlsisapd/examples/openChams/python/driveOpenChams.py b/vlsisapd/examples/openChams/python/driveOpenChams.py index 9bfad42d..95bcf9b2 100644 --- a/vlsisapd/examples/openChams/python/driveOpenChams.py +++ b/vlsisapd/examples/openChams/python/driveOpenChams.py @@ -92,5 +92,13 @@ op_nmos1.addConstraint("another", "myEq", -2.5 ) layout = circuit.createLayout() layout.addInstance("pmos1", "Common transistor") layout.addInstance("nmos1", "Rotate transistor") +# create hbtree +g1 = Group("g1") +g1.align = Group.Align.VERTICAL +b1 = Bloc("nmos1", Node.Position.NONE, g1) +g1.rootNode = b1 +b2 = Bloc("pmos1", Node.Position.TOP, b1) +b1.top = b2 +layout.hbTreeRoot = g1 circuit.writeToFile("./myInverter.xml") diff --git a/vlsisapd/examples/openChams/python/parseOpenChams.py b/vlsisapd/examples/openChams/python/parseOpenChams.py index a946e524..9917da8c 100644 --- a/vlsisapd/examples/openChams/python/parseOpenChams.py +++ b/vlsisapd/examples/openChams/python/parseOpenChams.py @@ -2,6 +2,23 @@ import sys from OPENCHAMS import * +def printHBTree(node, indent): + if node == None: + return + for i in range(indent): + print " |", + if isinstance(node, Bloc): + print " bloc:", node.getName(), "-", node.getPosition() + printHBTree(node.top , indent+1) + printHBTree(node.right, indent+1) + return + if isinstance(node, Group): + print " group:", node.getName(), "-", node.getPosition(), "-", node.align, "-", node.isolated, "-", node.paired + printHBTree(node.rootNode, indent+1) + printHBTree(node.top , indent+1) + printHBTree(node.right , indent+1) + return + def printContents(circuit): print circuit.name # circuit parameters @@ -78,6 +95,9 @@ def printContents(circuit): print " + layout" for inst in circuit.layout.getInstances(): print " | | instance name:", inst.key, "- style:", inst.value + if circuit.layout.hbTreeRoot != None: + print " | + hbtree" + printHBTree(circuit.layout.hbTreeRoot, 2) def usage(): print "usage:", sys.argv[0], "[filename]" diff --git a/vlsisapd/src/openChams/src/CMakeLists.txt b/vlsisapd/src/openChams/src/CMakeLists.txt index 61565be1..a308f8f3 100644 --- a/vlsisapd/src/openChams/src/CMakeLists.txt +++ b/vlsisapd/src/openChams/src/CMakeLists.txt @@ -12,6 +12,7 @@ SET ( hpps vlsisapd/openChams/Circuit.h vlsisapd/openChams/SimulModel.h vlsisapd/openChams/Sizing.h vlsisapd/openChams/Layout.h + vlsisapd/openChams/Node.h vlsisapd/openChams/Transistor.h vlsisapd/openChams/Port.h vlsisapd/openChams/Wire.h @@ -29,6 +30,7 @@ SET ( cpps Circuit.cpp SimulModel.cpp Sizing.cpp Layout.cpp + Node.cpp Transistor.cpp Wire.cpp ) diff --git a/vlsisapd/src/openChams/src/Circuit.cpp b/vlsisapd/src/openChams/src/Circuit.cpp index 8753970e..8751e08a 100644 --- a/vlsisapd/src/openChams/src/Circuit.cpp +++ b/vlsisapd/src/openChams/src/Circuit.cpp @@ -23,6 +23,7 @@ using namespace std; #include "vlsisapd/openChams/SimulModel.h" #include "vlsisapd/openChams/Sizing.h" #include "vlsisapd/openChams/Layout.h" +#include "vlsisapd/openChams/Node.h" #include "vlsisapd/openChams/Transistor.h" #include "vlsisapd/openChams/Operator.h" #include "vlsisapd/openChams/Port.h" @@ -688,6 +689,7 @@ void Circuit::readSizing(xmlNode* node) { } Sizing* sizing = new Sizing(this); + cerr << "** S ** " << node->name << ": " << node->type << endl; xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { @@ -796,12 +798,15 @@ void Circuit::readLayout(xmlNode* node) { Layout* layout = new Layout(this); xmlNode* child = node->children; + cerr << "** L ** " << node->name << ": " << node->type << endl; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"instance")) { readInstanceLayout(node, layout); + } else if (xmlStrEqual(node->name, (xmlChar*)"hbtree")) { + readHBTree(node, layout); } else { - cerr << "[WARNING] Only 'instance' nodes are allowed in 'sizing', others will be ignored." << endl; + cerr << "[WARNING] Only 'instance' and 'hbtree' nodes are allowed in 'layout' section, others will be ignored." << endl; } } } @@ -821,6 +826,90 @@ void Circuit::readInstanceLayout(xmlNode* node, Layout* layout) { } } +void Circuit::readHBTree(xmlNode* node, Layout* layout) { + // HBTree node can have only one child (group or bloc) + xmlNode* child = node->children; + if (child->type == XML_ELEMENT_NODE) { + // create root node + // thanks to readNodeOrBloc + Node* root = readNodeOrBloc(child); + // save root node in layout + layout->setHBTreeRoot(root); + } +} + +Node* Circuit::readNodeOrBloc(xmlNode* node, Node* parent) { + // 1 - create Node based on xmlNode* passed as argument + if (node->type == XML_ELEMENT_NODE) { + bool isAGroup = xmlStrEqual(node->name, (xmlChar*)"group"); + xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); + xmlChar* posiC = xmlGetProp(node, (xmlChar*)"position"); + if (!nameC) + throw OpenChamsException("[ERROR] 'bloc' and 'group' nodes in 'hbtree' must have at least a 'name' property."); + Node* nodeOC = NULL; + Name name ((const char*)nameC); + Node::Position pos = Node::NONE; + if (posiC) { + string posStr ((const char*)posiC); + if (posStr == "right") pos = Node::RIGHT; + else if (posStr == "top") pos = Node::TOP; + else throw OpenChamsException("[ERROR] 'position' property of 'bloc' and 'group' nodes must be 'right' or 'top'."); + } + if (isAGroup) { + Group* groupOC = new Group(name, pos, parent); + xmlChar* isolatC = xmlGetProp(node, (xmlChar*)"isolation"); + xmlChar* alignC = xmlGetProp(node, (xmlChar*)"align"); + xmlChar* pairedC = xmlGetProp(node, (xmlChar*)"paired"); + if (isolatC) { + string isolation ((const char*)isolatC); + if (isolation == "true") groupOC->setIsolated(true); + else if (isolation == "false") groupOC->setIsolated(false); + else throw OpenChamsException("[ERROR] 'isolation' property of 'group' node must be 'true' or 'false'."); + } + if (alignC) { + string align ((const char*)alignC); + Group::Align galign = Group::NONE; + if (align == "vertical") galign = Group::VERTICAL; + else if (align == "horizontal") galign = Group::HORIZONTAL; + else throw OpenChamsException("[ERROR] 'align' property of 'group' node must be 'vertical' or 'horizontal'."); + groupOC->setAlign(galign); + } + if (pairedC) { + string paired ((const char*)pairedC); + if (paired == "true") groupOC->setPaired(true); + else if (paired == "false") groupOC->setPaired(false); + else throw OpenChamsException("[ERROR] 'paired' property of 'group' node must be 'true' or 'false'."); + } + nodeOC = groupOC; + } else { + nodeOC = new Bloc(name, pos, parent); + } + // 2 - for each children (up to 2) readNodeOrBloc + for (xmlNode* child = node->children; child; child = child->next) { + if (child->type == XML_ELEMENT_NODE) { + Node* childOC = readNodeOrBloc(child, nodeOC); + // 3 - add to returned Node* to current Node* as right or top children (based on its position) + switch(childOC->getPosition()) { + case Node::RIGHT: + nodeOC->setRight(childOC); + break; + case Node::TOP: + nodeOC->setTop(childOC); + break; + case Node::NONE: + if (!isAGroup) + throw OpenChamsException("[ERROR] a 'bloc' or 'group' without position is only allowed directly under a 'group'."); + Group* groupOC = dynamic_cast(nodeOC); + groupOC->setRootNode(childOC); + } + } + } + // 4 - return current Node + return nodeOC; + } + return NULL; +} + void Circuit::setAbsolutePath(const string filePath) { if (filePath[0] == '/') _absolutePath = filePath; @@ -835,7 +924,7 @@ Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; Circuit* cir = NULL; - xmlDoc* doc = xmlReadFile(filePath.c_str(), NULL, 0); + xmlDoc* doc = xmlReadFile(filePath.c_str(), NULL, XML_PARSE_NOBLANKS); if (doc == NULL) { string error ("[ERROR] Failed to parse: "); error += filePath; @@ -941,13 +1030,75 @@ Layout* Circuit::createLayout() { return _layout; } +void Circuit::driveHBTree(ofstream& file, Node* node, unsigned indent) { + if (!node) return; + for (unsigned i = 0 ; i < indent ; i++) + file << " "; + string pos = ""; + switch(node->getPosition()) { + case OpenChams::Node::TOP: + pos = "top"; + break; + case OpenChams::Node::RIGHT: + pos = "right"; + break; + default: + break; + } + + Bloc* bloc = dynamic_cast(node); + if (bloc) { + file << "getName().getString() << "\""; + if (pos != "") + file << " position=\"" << pos << "\""; + if (bloc->getTop() == NULL && bloc->getRight() == NULL) + file << "/>" << endl; + else { + file << ">" << endl; + driveHBTree(file, bloc->getTop() , indent+1); + driveHBTree(file, bloc->getRight(), indent+1); + for (unsigned i = 0 ; i < indent ; i++) + file << " "; + file << "" << endl; + } + return; + } + Group* group = dynamic_cast(node); + if (group) { + string align = ""; + switch(group->getAlign()) { + case OpenChams::Group::VERTICAL: + align = "vertical"; + break; + case OpenChams::Group::HORIZONTAL: + align = "horizontal"; + break; + default: + break; + } + file << "getName().getString() << "\""; + if (pos != "") file << " position=\"" << pos << "\""; + if (align != "") file << " align=\"" << align << "\""; + if (group->isIsolated()) file << " isolated=\"true\""; + if (group->isPaired()) file << " paired=\"true\""; + file << ">" << endl; + driveHBTree(file, group->getRootNode(), indent+1); + driveHBTree(file, group->getTop() , indent+1); + driveHBTree(file, group->getRight() , indent+1); + for (unsigned i = 0 ; i < indent ; i++) + file << " "; + file << "" << endl; + return; + } +} + bool Circuit::writeToFile(string filePath) { ofstream file; file.open(filePath.c_str()); if (!file.is_open()) { string error("[ERROR] Cannot open file "); error += filePath; - error += " for writting."; + error += " for writing."; throw OpenChamsException(error); } // checks before do anything @@ -1148,10 +1299,17 @@ bool Circuit::writeToFile(string filePath) { } file << " " << endl; } - if (_layout && !_layout->hasNoInstance()) { + if (_layout) { file << " " << endl; - for (map::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) { - file << " " << endl; + if (!_layout->hasNoInstance()) { + for (map::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) { + file << " " << endl; + } + } + if (Node* root = _layout->getHBTreeRoot()) { + file << " " << endl; + driveHBTree(file, root, 3); + file << " " << endl; } file << " " << endl; } diff --git a/vlsisapd/src/openChams/src/Layout.cpp b/vlsisapd/src/openChams/src/Layout.cpp index e478eb26..57de6285 100644 --- a/vlsisapd/src/openChams/src/Layout.cpp +++ b/vlsisapd/src/openChams/src/Layout.cpp @@ -3,7 +3,7 @@ * openChams * * Created by damien dupuis on 31/08/10. - * Copyright 2008-2010 UPMC / LIP6. All rights reserved. + * Copyright 2008-2011 UPMC / LIP6. All rights reserved. * */ @@ -15,7 +15,7 @@ using namespace std; #include "vlsisapd/openChams/OpenChamsException.h" namespace OpenChams { -Layout::Layout(Circuit* circuit): _circuit(circuit) {} +Layout::Layout(Circuit* circuit): _circuit(circuit), _hbTreeRoot(NULL), _instances() {} void Layout::addInstance(Name name, Name style) { map::iterator it = _instances.find(name); diff --git a/vlsisapd/src/openChams/src/Node.cpp b/vlsisapd/src/openChams/src/Node.cpp new file mode 100644 index 00000000..4c1e0f5e --- /dev/null +++ b/vlsisapd/src/openChams/src/Node.cpp @@ -0,0 +1,34 @@ +/* + * Node.cpp + * openChams + * + * Created by damien dupuis on 23/08/11. + * Copyright 2010-2011 UPMC / LIP6. All rights reserved. + * + */ + +using namespace std; + +#include "vlsisapd/openChams/Node.h" + +namespace OpenChams { +Node::Node(Name nodeName, Position pos, Node* parent) + : _name(nodeName) + , _position(pos) + , _parent(parent) + , _right(NULL) + , _top(NULL) +{} + +Bloc::Bloc(Name blocName, Position pos, Node* parent) + : Node(blocName, pos, parent) +{} + +Group::Group(Name groupName, Position pos, Node* parent) + : Node(groupName, pos, parent) + , _isolated(false) + , _paired(false) + , _align(Group::NONE) +{} + +} // namespace diff --git a/vlsisapd/src/openChams/src/PyOpenChams.cpp b/vlsisapd/src/openChams/src/PyOpenChams.cpp index db55aede..2eabf25b 100644 --- a/vlsisapd/src/openChams/src/PyOpenChams.cpp +++ b/vlsisapd/src/openChams/src/PyOpenChams.cpp @@ -16,6 +16,7 @@ using namespace boost::python; #include "vlsisapd/openChams/SimulModel.h" #include "vlsisapd/openChams/Sizing.h" #include "vlsisapd/openChams/Layout.h" +#include "vlsisapd/openChams/Node.h" #include "vlsisapd/openChams/Circuit.h" #include "vlsisapd/openChams/Port.h" #include "vlsisapd/openChams/Wire.h" @@ -317,6 +318,8 @@ BOOST_PYTHON_MODULE(OPENCHAMS) { STL_MAP_WRAPPING(Name, Name, "LayoutInstancesMap") // class OpenChams::Layout class_("Layout", init()) + // properties + .add_property("hbTreeRoot", make_function(&Layout::getHBTreeRoot, return_value_policy()), &Layout::setHBTreeRoot) // accessors .def("hasNoInstance", &Layout::hasNoInstance) // modifiers @@ -349,6 +352,47 @@ BOOST_PYTHON_MODULE(OPENCHAMS) { .def("writeToFile" , &Circuit::writeToFile) ; + { //this scope is used to define Position as a subenum of Node + // class OpenChams::Node + scope nod = class_("Node", no_init) + // properties + .add_property("top" , make_function(&Node::getTop , return_value_policy()), &Node::setTop ) + .add_property("right", make_function(&Node::getRight, return_value_policy()), &Node::setRight) + // accessors + .def("getName" , &Node::getName ) + .def("getPosition", &Node::getPosition) + .def("getParent" , &Node::getParent , return_value_policy()) + .def("isRoot" , &Node::isRoot ) + ; + + enum_("Position") + .value("NONE" , Node::NONE ) + .value("RIGHT", Node::RIGHT) + .value("TOP" , Node::TOP ) + .export_values() + ; + } // end of node scope + + // class OpenChams::Bloc + class_ >("Bloc", init >()) + ; + + { // this scope is used to define Align as a subenum of Group + // class OpenChams::Group + scope grou = class_ >("Group", init >()) + .add_property("rootNode", make_function(&Group::getRootNode, return_value_policy()), &Group::setRootNode) + .add_property("isolated", &Group::isIsolated, &Group::setIsolated) + .add_property("paired" , &Group::isPaired , &Group::setPaired ) + .add_property("align" , &Group::getAlign , &Group::setAlign ) + ; + + enum_("Align") + .value("NONE" , Group::NONE ) + .value("VERTICAL" , Group::VERTICAL ) + .value("HORIZONTAL", Group::HORIZONTAL) + ; + } // end of group scope + // OpenChamsException translator register_exception_translator(translator) ; diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h index b7230a2d..bee06c21 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h @@ -30,6 +30,7 @@ class Sizing; class Transistor; class Operator; class Layout; +class Node; class Circuit { public: @@ -57,6 +58,8 @@ class Circuit { Schematic* createSchematic(); Sizing* createSizing(); Layout* createLayout(); + + void driveHBTree(ofstream&, Node*, unsigned); bool writeToFile(std::string filePath); static Circuit* readFromFile(const std::string filePath); @@ -91,6 +94,8 @@ class Circuit { void readEquation(xmlNode*, Sizing*); void readLayout(xmlNode*); void readInstanceLayout(xmlNode*, Layout*); + void readHBTree(xmlNode*, Layout*); + Node* readNodeOrBloc(xmlNode*, Node* parent = NULL); void setAbsolutePath(const std::string filePath); void check_uppercase(std::string& str, std::vector& compares, std::string message); diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h index e6e167e2..e4602e0a 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Layout.h @@ -15,6 +15,7 @@ namespace OpenChams { class Name; class Circuit; +class Node; class Layout { public: @@ -24,14 +25,22 @@ class Layout { inline bool hasNoInstance(); inline const std::map& getInstances(); + + inline Node* getHBTreeRoot(); + inline void setHBTreeRoot(Node*); private: Circuit* _circuit; + Node* _hbTreeRoot; 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; }; +inline bool Layout::hasNoInstance() { return (_instances.size() == 0) ? true : false; }; +inline const std::map& Layout::getInstances() { return _instances; }; + +inline Node* Layout::getHBTreeRoot() { return _hbTreeRoot; } +inline void Layout::setHBTreeRoot(Node* root) { _hbTreeRoot = root; } + } // namespace #endif diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Node.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Node.h new file mode 100644 index 00000000..bbedcc61 --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Node.h @@ -0,0 +1,100 @@ +/* + * Node.h + * openChams + * + * Created by damien dupuis on 23/08/11. + * Copyright 2010-2011 UPMC / LIP6. All rights reserved. + * + */ + +#ifndef __OPENCHAMS_NODE_H__ +#define __OPENCHAMS_NODE_H__ + +#include "vlsisapd/openChams/Name.h" + +namespace OpenChams { +class Node { + public: + enum Position { NONE = 0, + RIGHT = 1, + TOP = 2 + }; + + protected: + Node(Name nodeName, Position pos, Node* parent); + virtual ~Node() {}; + + public: + inline Name getName() const; + inline Position getPosition() const; + inline Node* getParent(); + inline Node* getRight(); + inline Node* getTop(); + inline bool isRoot(); + + inline void setRight(Node*); + inline void setTop(Node*); + + private: + Name _name; + Position _position; + Node* _parent; + Node* _right; + Node* _top; +}; + +inline Name Node::getName() const { return _name; } +inline Node::Position Node::getPosition() const { return _position; } +inline Node* Node::getParent() { return _parent; } +inline Node* Node::getRight() { return _right; } +inline Node* Node::getTop() { return _top; } +inline bool Node::isRoot() { return _parent == NULL; } + +inline void Node::setRight(Node* right) { _right = right; } +inline void Node::setTop(Node* top) { _top = top; } + + +class Bloc : public Node { + public: + Bloc(Name blocName, Position pos=Node::NONE, Node* parent=NULL); +}; + +class Group : public Node { + public: + enum Align { NONE = 0 + , VERTICAL = 1 + , HORIZONTAL = 2 + }; + + Group(Name groupName, Position pos=Node::NONE, Node* parent=NULL); + + inline void setRootNode(Node*); + inline void setIsolated(bool); + inline void setPaired(bool); + inline void setAlign(Align); + + inline Node* getRootNode(); + inline bool isIsolated(); + inline bool isPaired(); + inline Align getAlign(); + + private: + Node* _root; + bool _isolated; + bool _paired; + Align _align; +}; + +inline void Group::setRootNode(Node* root) { _root = root; } +inline void Group::setIsolated(bool isolated) { _isolated = isolated; } +inline void Group::setPaired(bool paired) { _paired = paired; } +inline void Group::setAlign(Group::Align align) { _align = align; } + +inline Node* Group::getRootNode() { return _root; } +inline bool Group::isIsolated() { return _isolated; } +inline bool Group::isPaired() { return _paired; } +inline Group::Align Group::getAlign() { return _align; } + +} // namespace +#endif +