- New support for <hbtree> section in <layout> section used to describe relative placement with constraints
- Examples (c++/python parse/drive) have been updated TODO: test under linux / write corresponding documentation
This commit is contained in:
parent
8bb398b88f
commit
c6ab2d5ed8
|
@ -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;
|
||||
|
|
|
@ -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<OpenChams::Bloc*>(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<OpenChams::Group*>(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<OpenChams::Name, OpenChams::Name>::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<OpenChams::Name, OpenChams::Name>::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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -119,5 +119,12 @@
|
|||
<layout>
|
||||
<instance name="pmos1" style="Common transistor"/>
|
||||
<instance name="nmos1" style="Rotate transistor"/>
|
||||
<hbtree>
|
||||
<group name="g1" align="vertical">
|
||||
<bloc name="nmos1">
|
||||
<bloc name="pmos1" position="top"/>
|
||||
</bloc>
|
||||
</group>
|
||||
</hbtree>
|
||||
</layout>
|
||||
</circuit>
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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]"
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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<Group*>(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<Bloc*>(node);
|
||||
if (bloc) {
|
||||
file << "<bloc name=\"" << bloc->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 << "</bloc>" << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
Group* group = dynamic_cast<Group*>(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 << "<group name=\"" << group->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 << "</group>" << 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 << " </sizing>" << endl;
|
||||
}
|
||||
if (_layout && !_layout->hasNoInstance()) {
|
||||
if (_layout) {
|
||||
file << " <layout>" << endl;
|
||||
for (map<Name, Name>::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) {
|
||||
file << " <instance name=\"" << ((*it).first).getString() << "\" style=\"" << ((*it).second).getString() << "\"/>" << endl;
|
||||
if (!_layout->hasNoInstance()) {
|
||||
for (map<Name, Name>::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) {
|
||||
file << " <instance name=\"" << ((*it).first).getString() << "\" style=\"" << ((*it).second).getString() << "\"/>" << endl;
|
||||
}
|
||||
}
|
||||
if (Node* root = _layout->getHBTreeRoot()) {
|
||||
file << " <hbtree>" << endl;
|
||||
driveHBTree(file, root, 3);
|
||||
file << " </hbtree>" << endl;
|
||||
}
|
||||
file << " </layout>" << endl;
|
||||
}
|
||||
|
|
|
@ -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<Name, Name>::iterator it = _instances.find(name);
|
||||
|
|
|
@ -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
|
|
@ -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, Layout*>("Layout", init<Circuit*>())
|
||||
// properties
|
||||
.add_property("hbTreeRoot", make_function(&Layout::getHBTreeRoot, return_value_policy<reference_existing_object>()), &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, Node*, boost::noncopyable>("Node", no_init)
|
||||
// properties
|
||||
.add_property("top" , make_function(&Node::getTop , return_value_policy<reference_existing_object>()), &Node::setTop )
|
||||
.add_property("right", make_function(&Node::getRight, return_value_policy<reference_existing_object>()), &Node::setRight)
|
||||
// accessors
|
||||
.def("getName" , &Node::getName )
|
||||
.def("getPosition", &Node::getPosition)
|
||||
.def("getParent" , &Node::getParent , return_value_policy<reference_existing_object>())
|
||||
.def("isRoot" , &Node::isRoot )
|
||||
;
|
||||
|
||||
enum_<Node::Position>("Position")
|
||||
.value("NONE" , Node::NONE )
|
||||
.value("RIGHT", Node::RIGHT)
|
||||
.value("TOP" , Node::TOP )
|
||||
.export_values()
|
||||
;
|
||||
} // end of node scope
|
||||
|
||||
// class OpenChams::Bloc
|
||||
class_<Bloc, bases<Node> >("Bloc", init<Name, optional<Node::Position, Node*> >())
|
||||
;
|
||||
|
||||
{ // this scope is used to define Align as a subenum of Group
|
||||
// class OpenChams::Group
|
||||
scope grou = class_<Group, bases<Node> >("Group", init<Name, optional<Node::Position, Node*> >())
|
||||
.add_property("rootNode", make_function(&Group::getRootNode, return_value_policy<reference_existing_object>()), &Group::setRootNode)
|
||||
.add_property("isolated", &Group::isIsolated, &Group::setIsolated)
|
||||
.add_property("paired" , &Group::isPaired , &Group::setPaired )
|
||||
.add_property("align" , &Group::getAlign , &Group::setAlign )
|
||||
;
|
||||
|
||||
enum_<Group::Align>("Align")
|
||||
.value("NONE" , Group::NONE )
|
||||
.value("VERTICAL" , Group::VERTICAL )
|
||||
.value("HORIZONTAL", Group::HORIZONTAL)
|
||||
;
|
||||
} // end of group scope
|
||||
|
||||
// OpenChamsException translator
|
||||
register_exception_translator<OpenChamsException>(translator)
|
||||
;
|
||||
|
|
|
@ -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<std::string>& compares, std::string message);
|
||||
|
|
|
@ -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<Name, Name>& getInstances();
|
||||
|
||||
inline Node* getHBTreeRoot();
|
||||
inline void setHBTreeRoot(Node*);
|
||||
|
||||
private:
|
||||
Circuit* _circuit;
|
||||
Node* _hbTreeRoot;
|
||||
std::map<Name, Name> _instances; // device name <-> style (name)
|
||||
};
|
||||
};
|
||||
|
||||
inline bool Layout::hasNoInstance() { return (_instances.size() == 0) ? true : false; };
|
||||
inline const std::map<Name, Name>& Layout::getInstances() { return _instances; };
|
||||
inline bool Layout::hasNoInstance() { return (_instances.size() == 0) ? true : false; };
|
||||
inline const std::map<Name, Name>& Layout::getInstances() { return _instances; };
|
||||
|
||||
inline Node* Layout::getHBTreeRoot() { return _hbTreeRoot; }
|
||||
inline void Layout::setHBTreeRoot(Node* root) { _hbTreeRoot = root; }
|
||||
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue