From 5809fc7aa00596d1037280bfa66cf14b0b624c98 Mon Sep 17 00:00:00 2001 From: EricLaoGitHub Date: Tue, 16 Feb 2016 19:21:37 +0100 Subject: [PATCH] Modifications in OpenChams description: - Add OpenChams::SlicingNode class to drive/parse XML files. OpenChams::SlicingNode contains information to create a real slicing tree (SlicingNode from hurricaneAMS) - Minor modification in Circuit.cpp for case when HBTree are not described in XML file. --- bootstrap/build.conf | 1 + vlsisapd/CMakeLists.txt | 1 + vlsisapd/src/openChams/src/CMakeLists.txt | 43 +- vlsisapd/src/openChams/src/Circuit.cpp | 758 ++++++++---- vlsisapd/src/openChams/src/SlicingTree.cpp | 1088 +++++++++++++++++ .../src/vlsisapd/openChams/Circuit.h | 21 +- .../src/vlsisapd/openChams/SlicingTree.h | 392 ++++++ 7 files changed, 2046 insertions(+), 258 deletions(-) create mode 100644 vlsisapd/src/openChams/src/SlicingTree.cpp create mode 100644 vlsisapd/src/openChams/src/vlsisapd/openChams/SlicingTree.h diff --git a/bootstrap/build.conf b/bootstrap/build.conf index 8447c0e8..e18839b7 100644 --- a/bootstrap/build.conf +++ b/bootstrap/build.conf @@ -38,6 +38,7 @@ projects = [ , "graph" , "pharos" , "isis" + , "horus" #, "schematic" , "solver" , "autoDTR" diff --git a/vlsisapd/CMakeLists.txt b/vlsisapd/CMakeLists.txt index 9799c64c..82b25d43 100644 --- a/vlsisapd/CMakeLists.txt +++ b/vlsisapd/CMakeLists.txt @@ -20,6 +20,7 @@ find_package(BISON REQUIRED) find_package(FLEX REQUIRED) find_package(Doxygen) + find_package(HURRICANE REQUIRED) add_subdirectory(src) add_subdirectory(cmake_modules) diff --git a/vlsisapd/src/openChams/src/CMakeLists.txt b/vlsisapd/src/openChams/src/CMakeLists.txt index 01f87f6e..0d86e749 100644 --- a/vlsisapd/src/openChams/src/CMakeLists.txt +++ b/vlsisapd/src/openChams/src/CMakeLists.txt @@ -1,4 +1,9 @@ -INCLUDE_DIRECTORIES(${VLSISAPD_SOURCE_DIR}/src/openChams/src ${LIBXML2_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH}) +INCLUDE_DIRECTORIES( ${VLSISAPD_SOURCE_DIR}/src/openChams/src + ${LIBXML2_INCLUDE_DIR} + ${Boost_INCLUDE_DIRS} + ${PYTHON_INCLUDE_PATH} + ${HURRICANE_INCLUDE_DIR} + ) SET ( hpps vlsisapd/openChams/Circuit.h vlsisapd/openChams/Netlist.h @@ -21,6 +26,7 @@ SET ( hpps vlsisapd/openChams/Circuit.h vlsisapd/openChams/NRCCstr.h vlsisapd/openChams/DDP.h vlsisapd/openChams/DesignerCstrOC.h + vlsisapd/openChams/SlicingTree.h ) SET ( cpps Circuit.cpp Netlist.cpp @@ -41,23 +47,24 @@ SET ( cpps Circuit.cpp NRCCstr.cpp DDP.cpp DesignerCstrOC.cpp - ) -SET ( pycpps PyOpenChams.cpp - ) + SlicingTree.cpp + ) + SET ( pycpps PyOpenChams.cpp + ) -ADD_LIBRARY(openChams ${cpps}) -TARGET_LINK_LIBRARIES(openChams ${LIBXML2_LIBRARIES}) -SET_TARGET_PROPERTIES(openChams PROPERTIES VERSION 1.0 SOVERSION 1) -INSTALL(TARGETS openChams DESTINATION lib${LIB_SUFFIX} ) + ADD_LIBRARY(openChams ${cpps}) + TARGET_LINK_LIBRARIES(openChams ${LIBXML2_LIBRARIES}) + SET_TARGET_PROPERTIES(openChams PROPERTIES VERSION 1.0 SOVERSION 1) + INSTALL(TARGETS openChams DESTINATION lib${LIB_SUFFIX} ) -IF(Boost_FOUND) - ADD_LIBRARY(pyOPENCHAMS MODULE ${pycpps}) - SET_TARGET_PROPERTIES(pyOPENCHAMS PROPERTIES - OUTPUT_NAME "OPENCHAMS" - PREFIX "" - ) - TARGET_LINK_LIBRARIES(pyOPENCHAMS openChams ${LIBXML2_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) - INSTALL(TARGETS pyOPENCHAMS DESTINATION ${PYTHON_SITE_PACKAGES}) -ENDIF(Boost_FOUND) + IF(Boost_FOUND) + ADD_LIBRARY(pyOPENCHAMS MODULE ${pycpps}) + SET_TARGET_PROPERTIES(pyOPENCHAMS PROPERTIES + OUTPUT_NAME "OPENCHAMS" + PREFIX "" + ) + TARGET_LINK_LIBRARIES(pyOPENCHAMS openChams ${LIBXML2_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) + INSTALL(TARGETS pyOPENCHAMS DESTINATION ${PYTHON_SITE_PACKAGES}) + ENDIF(Boost_FOUND) -INSTALL(FILES ${hpps} DESTINATION include/vlsisapd/openChams) + INSTALL(FILES ${hpps} DESTINATION include/vlsisapd/openChams) diff --git a/vlsisapd/src/openChams/src/Circuit.cpp b/vlsisapd/src/openChams/src/Circuit.cpp index a0d2512e..38fb6600 100644 --- a/vlsisapd/src/openChams/src/Circuit.cpp +++ b/vlsisapd/src/openChams/src/Circuit.cpp @@ -2,13 +2,14 @@ // -*- C++ -*- // // This file is part of the VLSI SAPD Software. -// Copyright (c) UPMC/LIP6 2009-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2009-2016, All Rights Reserved // // +-----------------------------------------------------------------+ // | V L S I S A P D | // | OpenChams Circuit Data Base | // | | // | Author : Damien Dupuis | +// | Eric Lao | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./Circuit.cpp" | @@ -152,6 +153,7 @@ namespace OpenChams { static bool readSchematicDone = false; static bool readSizingDone = false; static bool readLayoutDone = false; + static bool readSlicingTreeDone = false; Circuit::Circuit(const std::string& name, const std::string& techno) : _name (name) @@ -161,6 +163,7 @@ namespace OpenChams { , _schematic (NULL) , _sizing (NULL) , _layout (NULL) + , _slicingtree (NULL) { readSubCircuitsPathsDone = false; readCircuitParametersDone = false; @@ -981,16 +984,16 @@ namespace OpenChams { Layout* layout = new Layout(this); xmlNode* child = node->children; - //cerr << "** L ** " << node->name << ": " << node->type << endl; + //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' and 'hbtree' nodes are allowed in 'layout' section, others will be ignored." << endl; - } + if (xmlStrEqual(node->name, (xmlChar*)"instance")) { + readInstanceLayout(node, layout); + } else if (xmlStrEqual(node->name, (xmlChar*)"hbtree")) { + readHBTree(node, layout); + } else { + cerr << "[WARNING] Only 'instance' and 'hbtree' nodes are allowed in 'layout' section, others will be ignored." << endl; + } } } readLayoutDone = true; @@ -1010,10 +1013,10 @@ namespace OpenChams { } void Circuit::readHBTree(xmlNode* node, Layout* layout) { - // HBTree node can have only one child (group or bloc) + // HBTree node can have only one child (group or bloc) xmlNode* child = node->children; if (child->type == XML_ELEMENT_NODE) { - // create root node + // create root node // thanks to readNodeOrBloc Node* root = readNodeOrBloc(child); // save root node in layout @@ -1022,70 +1025,70 @@ namespace OpenChams { } Node* Circuit::readNodeOrBloc(xmlNode* node, Node* parent) { - // 1 - create Node based on xmlNode* passed as argument + // 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."); + throw OpenChamsException("[ERROR] 'bloc' and 'group' nodes in 'hbtree' must have at least a 'name' property."); Node* nodeOC = NULL; const std::string& 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'."); + 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; + 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); + nodeOC = new Bloc(name, pos, parent); } - // 2 - for each children (up to 2) readNodeOrBloc + // 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); - } - } + 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; @@ -1103,6 +1106,254 @@ namespace OpenChams { _absolutePath = _absolutePath.substr(0, found); } + + // SLICINGTREE // + void Circuit::readSlicingTree(xmlNode* node) { + if (readSlicingTreeDone) { + cerr << "[WARNING] Only one 'slicingtree' is allowed in circuit, others will be ignored." << endl; + return; + } + _slicingtree = readSlicingNode(node); + readSlicingTreeDone = true; + } + + SlicingNode* Circuit::readSlicingNode(xmlNode* xnode, SlicingNode* slicingNode) { + SlicingNode* snode = NULL; + + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name , (xmlChar*)"vertical" )) { + snode = createVerticalSlicingNode (node, slicingNode); + } else if (xmlStrEqual(node->name , (xmlChar*)"horizontal")) { + snode = createHorizontalSlicingNode(node, slicingNode); + } else if (xmlStrEqual(node->name , (xmlChar*)"device" )) { + snode = createDeviceSlicingNode (node, slicingNode); + } else if (xmlStrEqual(node->name , (xmlChar*)"routing" )) { + snode = createRoutingSlicingNode (node, slicingNode); + } else if (!xmlStrEqual(node->name, (xmlChar*)"comment" )) { + cerr << "[WARNING] Unknown " << node->name << " node in 'slicingtree' section, it will be ignored." << endl; + } + } + } + return snode; + } + + VSlicingNode* Circuit::createVerticalSlicingNode (xmlNode* xnode, SlicingNode* slicingNode) { + VSlicingNode* vnode = VSlicingNode::create(slicingNode); + + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + if (xmlStrEqual(node->name , (xmlChar*)"parameters")) { + setHVParameters(node, vnode); + } else if (xmlStrEqual(node->name, (xmlChar*)"symmetries")) { + setHVSymmetries(node, vnode); + } else if (xmlStrEqual(node->name, (xmlChar*)"children" )) { + addChildren(node, vnode); + } else if (!xmlStrEqual(node->name,(xmlChar*)"comment" )) { + cerr << "[WARNING] Unknown " << node->name << " node in 'vertical' section, it will be ignored." << endl; + } + } + return vnode; + } + + HSlicingNode* Circuit::createHorizontalSlicingNode (xmlNode* xnode, SlicingNode* slicingNode) { + HSlicingNode* hnode = HSlicingNode::create(slicingNode); + + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + if (xmlStrEqual(node->name, (xmlChar*)"children")) { + addChildren(node, hnode); + } else if (xmlStrEqual(node->name , (xmlChar*)"parameters")) { + setHVParameters(node, hnode); + } else if (xmlStrEqual(node->name , (xmlChar*)"symmetries")) { + setHVSymmetries(node, hnode); + } else if (!xmlStrEqual(node->name, (xmlChar*)"comment" )){ + cerr << "[WARNING] Unknown " << node->name << " node in 'horizontal' section, it will be ignored." << endl; + } + } + return hnode; + } + + void Circuit::addChildren (xmlNode* xnode, HVSlicingNode* hvnode) { + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name , (xmlChar*)"vertical" )) { + hvnode->push_back(createVerticalSlicingNode (node, hvnode)); + } else if (xmlStrEqual(node->name , (xmlChar*)"horizontal")) { + hvnode->push_back(createHorizontalSlicingNode(node, hvnode)); + } else if (xmlStrEqual(node->name , (xmlChar*)"device" )) { + hvnode->push_back(createDeviceSlicingNode (node, hvnode)); + } else if (xmlStrEqual(node->name , (xmlChar*)"routing" )) { + hvnode->push_back(createRoutingSlicingNode (node, hvnode)); + } else if (!xmlStrEqual(node->name, (xmlChar*)"comment" )){ + cerr << "[WARNING] Unknown " << node->name << " node in 'slicingtree' section, it will be ignored." << endl; + } + } + } + } + + void Circuit::setHVParameters (xmlNode* xnode, HVSlicingNode* hvnode) { + bool toleranceRatioHSet = false; + bool toleranceRatioWSet = false; + bool toleranceBandHSet = false; + bool toleranceBandWSet = false; + + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + xmlChar* typeC = xmlGetProp(node, (xmlChar*)"type"); + + if (typeC) { + string type ((const char*)typeC); + + if (type == "alignment") { + xmlChar* alignmentC = xmlGetProp(node, (xmlChar*)"alignment"); + if (alignmentC){ + string alignment ((const char*)alignmentC); + hvnode->setAlignment(alignment); + } + } else if (type == "toleranceBandH") { + xmlChar* toleranceBandHC = xmlGetProp(node, (xmlChar*)"toleranceBandH"); + if (toleranceBandHC){ + string toleranceBandH ((const char*)toleranceBandHC); + hvnode->setToleranceBandH(toleranceBandH); + toleranceBandHSet = true; + } + } else if (type == "toleranceBandW") { + xmlChar* toleranceBandWC = xmlGetProp(node, (xmlChar*)"toleranceBandW"); + if (toleranceBandWC){ + string toleranceBandW ((const char*)toleranceBandWC); + hvnode->setToleranceBandW(toleranceBandW); + toleranceBandWSet = true; + } + } else if (type == "toleranceRatioH") { + xmlChar* toleranceRatioHC = xmlGetProp(node, (xmlChar*)"toleranceRatioH"); + if (toleranceRatioHC){ + string toleranceRatioH ((const char*)toleranceRatioHC); + hvnode->setToleranceRatioH(toleranceRatioH); + toleranceRatioHSet = true; + } + } else if (type == "toleranceRatioW") { + xmlChar* toleranceRatioWC = xmlGetProp(node, (xmlChar*)"toleranceRatioW"); + if (toleranceRatioWC){ + string toleranceRatioW ((const char*)toleranceRatioWC); + hvnode->setToleranceRatioW(toleranceRatioW); + toleranceRatioWSet = true; + } + } else if (!xmlStrEqual(node->name, (xmlChar*)"comment" )){ + cerr << "[WARNING] Unknown " << node->name << " node in 'HVparameters' section, it will be ignored." << endl; + } + } + } + + if (!hvnode->isRoot()){ + if (!toleranceRatioHSet){ + hvnode->setToleranceRatioH(hvnode->getParent()->getToleranceRatioH()); + } + if (!toleranceRatioWSet){ + hvnode->setToleranceRatioW(hvnode->getParent()->getToleranceRatioW()); + } + if (!toleranceBandHSet){ + hvnode->setToleranceBandH(hvnode->getParent()->getToleranceBandH()); + } + if (!toleranceBandWSet){ + hvnode->setToleranceBandW(hvnode->getParent()->getToleranceBandW()); + } + } + } + + void Circuit::setHVSymmetries (xmlNode* xnode, HVSlicingNode* hvnode) { + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + xmlChar* sourceC = xmlGetProp(node, (xmlChar*)"source"); + xmlChar* targetC = xmlGetProp(node, (xmlChar*)"target"); + if ((sourceC)&&(targetC)) { + string source ((const char*)sourceC); + string target ((const char*)targetC); + hvnode->addSymmetry(source, target); + } else if (!xmlStrEqual(node->name, (xmlChar*)"comment" )){ + cerr << "[WARNING] Unknown " << node->name << " node in 'HVsymmetries' section, it will be ignored." << endl; + } + } + } + + DSlicingNode* Circuit::createDeviceSlicingNode (xmlNode* xnode, SlicingNode* slicingNode) { + DSlicingNode* dnode = NULL; + + xmlChar* instanceNameC = xmlGetProp(xnode, (xmlChar*)"instance"); + if (instanceNameC){ + string instanceName ((const char*)instanceNameC); + dnode = DSlicingNode::create( instanceName, slicingNode ); + + xmlNode* child = xnode->children; + for (xmlNode* node = child; node; node = node->next) { + xmlChar* typeC = xmlGetProp(node, (xmlChar*)"type"); + if (typeC) { + string type ((const char*)typeC); + + if (type == "alignment") { + xmlChar* alignmentC = xmlGetProp(node, (xmlChar*)"alignment"); + if (alignmentC){ + string alignment ((const char*)alignmentC); + dnode->setAlignment(alignment); + } + } else if (type == "preset") { + xmlChar* presetC = xmlGetProp(node, (xmlChar*)"preset"); + if (presetC){ + string preset ((const char*)presetC); + dnode->setPreset(preset); + } + } else if (type == "nfing") { + xmlChar* nfingC = xmlGetProp(node, (xmlChar*)"nfing"); + if (nfingC){ + string nfing ((const char*)nfingC); + dnode->setNFing(nfing); + } + } else if (type == "x") { + xmlChar* xC = xmlGetProp(node, (xmlChar*)"x"); + if (xC){ + string x ((const char*)xC); + dnode->setX(x); + } + } else if (type == "y") { + xmlChar* yC = xmlGetProp(node, (xmlChar*)"y"); + if (yC){ + string y ((const char*)yC); + dnode->setY(y); + } + } else if (type == "nodeSets") { + xmlChar* startC = xmlGetProp(node, (xmlChar*)"start"); + xmlChar* stepC = xmlGetProp(node, (xmlChar*)"step"); + xmlChar* countC = xmlGetProp(node, (xmlChar*)"count"); + if ( (startC) && (stepC) && (countC) ){ + string start ((const char*)startC); + string step ((const char*)stepC); + string count ((const char*)countC); + dnode->setStart(start); + dnode->setStep (step); + dnode->setCount(count); + } + } else + cerr << "[WARNING] Unknown " << type << " type in 'device/parameter' section, it will be ignored." << endl; + } else if (!xmlStrEqual(node->name, (xmlChar*)"comment" )){ + cerr << "[WARNING] Unknown " << node->name << " node in 'device' section, it will be ignored." << endl; + } + } + } + return dnode; + } + + RSlicingNode* Circuit::createRoutingSlicingNode (xmlNode* xnode, SlicingNode* slicingNode) { + RSlicingNode* rnode = NULL; + xmlChar* valueC = xmlGetProp(xnode, (xmlChar*)"value"); + if (valueC){ + string value ((const char*)valueC); + rnode = RSlicingNode::create(value, slicingNode); + } + return rnode; + } + Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; Circuit* cir = NULL; @@ -1112,7 +1363,7 @@ namespace OpenChams { string error ("[ERROR] Failed to parse: "); error += filePath; throw OpenChamsException(error); - //return NULL; + //return NULL; } xmlNode* rootElement = xmlDocGetRootElement(doc); if (rootElement->type == XML_ELEMENT_NODE && xmlStrEqual(rootElement->name, (xmlChar*)"circuit")) { @@ -1120,47 +1371,50 @@ namespace OpenChams { xmlChar* technoNameC = xmlGetProp(rootElement, (xmlChar*)"techno"); if (circuitNameC && technoNameC) { - const std::string& circuitName ((const char*)circuitNameC); - const std::string& technoName ((const char*)technoNameC); - cir = new Circuit(circuitName, technoName); + const std::string& circuitName ((const char*)circuitNameC); + const std::string& technoName ((const char*)technoNameC); + cir = new Circuit(circuitName, technoName); } else { - throw OpenChamsException("[ERROR] 'circuit' node must have 'name' and 'techno' properties."); - return NULL; + throw OpenChamsException("[ERROR] 'circuit' node must have 'name' and 'techno' properties."); + return NULL; } cir->setAbsolutePath(filePath); xmlNode* child = rootElement->children; for (xmlNode* node = child; node; node = node->next) { - if (node->type == XML_ELEMENT_NODE) { - if (xmlStrEqual(node->name, (xmlChar*)"subCircuitsPaths")) { - cir->readSubCircuitsPaths(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { - cir->readCircuitParameters(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"simulModels")) { - cir->readSimulModels(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { - cir->readNetList(node); - } - else if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { - cir->readSchematic(node); - } - 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); - error += " in circuit description."; - throw OpenChamsException(error); - return NULL; - } - } + if (node->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(node->name, (xmlChar*)"subCircuitsPaths")) { + cir->readSubCircuitsPaths(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { + cir->readCircuitParameters(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"simulModels")) { + cir->readSimulModels(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { + cir->readNetList(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { + cir->readSchematic(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { + cir->readSizing(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"layout")) { + cir->readLayout(node); + } + else if (xmlStrEqual(node->name, (xmlChar*)"slicingtree")) { + cir->readSlicingTree(node); + } + else { + string error("[ERROR] Unknown section "); + error += string((const char*)node->name); + error += " in circuit description."; + throw OpenChamsException(error); + return NULL; + } + } } } if (!readNetListDone) { @@ -1213,6 +1467,16 @@ namespace OpenChams { return _layout; } + void Circuit::setSlicingTree( SlicingNode* slicingtree ) { + if (_slicingtree) + throw OpenChamsException("[ERROR] Cannot create two slicing trees in one circuit."); + + _slicingtree = slicingtree; + if (!_slicingtree) + throw OpenChamsException("[ERROR] Cannot create slicingtree."); + + } + void Circuit::driveHBTree(ofstream& file, Node* node, unsigned indent) { if (!node) return; for (unsigned i = 0 ; i < indent ; i++) @@ -1233,16 +1497,16 @@ namespace OpenChams { if (bloc) { file << "getName() << "\""; if (pos != "") - file << " position=\"" << pos << "\""; + file << " position=\"" << pos << "\""; if (bloc->getTop() == NULL && bloc->getRight() == NULL) - file << "/>" << endl; + 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; + 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; } @@ -1275,6 +1539,17 @@ namespace OpenChams { } } + void Circuit::driveSlicingTree(ofstream& file, SlicingNode* snode, unsigned indent) { + if (!snode) return; + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + + snode->toXML(file, indent+1); + + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + } + bool Circuit::writeToFile(string filePath) { ofstream file; file.open(filePath.c_str()); @@ -1284,21 +1559,21 @@ namespace OpenChams { error += " for writing."; throw OpenChamsException(error); } - // checks before do anything + // checks before do anything if (!_netlist) { - //cerr << "no netlist" << endl; cerr.flush(); + //cerr << "no netlist" << endl; cerr.flush(); throw OpenChamsException("[ERROR] Cannot writeToFile since no netlist is defined !"); - //return false; + //return false; } if (_netlist->hasNoInstances()) { - //cerr << "no instances" << endl; cerr.flush(); + //cerr << "no instances" << endl; cerr.flush(); throw OpenChamsException("[ERROR] Cannot writeToFile since no instance is defined in netlist !"); - //return false; + //return false; } if (_netlist->hasNoNets()) { - //cerr << "no nets" << endl; cerr.flush(); + //cerr << "no nets" << endl; cerr.flush(); throw OpenChamsException("[ERROR] Cannot writeToFile since no net is defined in netlist !"); - //return false; + //return false; } file << "" << endl @@ -1306,7 +1581,7 @@ namespace OpenChams { if (_subCircuitsPaths.size() != 0) { file << " " << endl; for (size_t i = 0 ; i < _subCircuitsPaths.size() ; i++ ) { - file << " " << endl; + file << " " << endl; } file << " " << endl; } @@ -1315,7 +1590,7 @@ namespace OpenChams { for (map::const_iterator it = _params.getValues().begin() ; it != _params.getValues().end() ; ++it) { file << " " << endl; } - //cerr << "_params.getValues().size() = " << _params.getValues().size() << endl; + //cerr << "_params.getValues().size() = " << _params.getValues().size() << endl; file << " " << endl; } file << " " << endl @@ -1326,46 +1601,46 @@ namespace OpenChams { Instance* inst = (*it); Device* dev = dynamic_cast(inst); if (inst->hasNoConnectors()) { - string error("[ERROR] Cannot writeToFile since instance ("); - error += inst->getName(); - error += ") has no connectors !"; - throw OpenChamsException(error); - //return false; + string error("[ERROR] Cannot writeToFile since instance ("); + error += inst->getName(); + error += ") has no connectors !"; + throw OpenChamsException(error); + //return false; } if (dev && dev->hasNoTransistors()) { - string error("[ERROR] Cannot writeToFile since device instance ("); - error += dev->getName(); - error += ") has no transistors !"; - throw OpenChamsException(error); + string error("[ERROR] Cannot writeToFile since device instance ("); + error += dev->getName(); + error += ") has no transistors !"; + throw OpenChamsException(error); } if (dev) { - string sourceBulkStr = (dev->isSourceBulkConnected()) ? "True" : "False"; - file << " getName() << "\" model=\"" << dev->getModel() << "\" mostype=\"" << dev->getMosType() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\" order=\"" << dev->getOrder() << "\">" << endl; + string sourceBulkStr = (dev->isSourceBulkConnected()) ? "True" : "False"; + file << " getName() << "\" model=\"" << dev->getModel() << "\" mostype=\"" << dev->getMosType() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\" order=\"" << dev->getOrder() << "\">" << endl; } else { - file << " getName() << "\" model=\"" << inst->getModel() << "\" order=\"" << inst->getOrder() << "\">" << endl; + file << " getName() << "\" model=\"" << inst->getModel() << "\" order=\"" << inst->getOrder() << "\">" << endl; } file << " " << endl; for (map::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { - file << " " << endl; + file << " " << endl; } file << " " << endl; if (dev) { - file << " " << endl; - for (vector::const_iterator it = dev->getTransistors().begin() ; it != dev->getTransistors().end() ; ++it ) { - Transistor* tr = (*it); - file << " getName() << "\">" << endl - << " getGate() << "\" source=\"" << tr->getSource() << "\" drain=\"" << tr->getDrain() << "\" bulk=\"" << tr->getBulk() << "\"/>" << endl - << " " << endl; - } - file << " " << endl; + file << " " << endl; + for (vector::const_iterator it = dev->getTransistors().begin() ; it != dev->getTransistors().end() ; ++it ) { + Transistor* tr = (*it); + file << " getName() << "\">" << endl + << " getGate() << "\" source=\"" << tr->getSource() << "\" drain=\"" << tr->getDrain() << "\" bulk=\"" << tr->getBulk() << "\"/>" << endl + << " " << endl; + } + file << " " << endl; } if (!inst->getParameters().isEmpty()) { - Parameters params = inst->getParameters(); - file << " " << endl; - for (map::const_iterator it = params.getValues().begin() ; it != params.getValues().end() ; ++it) { - file << " " << endl; - } - file << " " << endl; + Parameters params = inst->getParameters(); + file << " " << endl; + for (map::const_iterator it = params.getValues().begin() ; it != params.getValues().end() ; ++it) { + file << " " << endl; + } + file << " " << endl; } file << " " << endl; } @@ -1377,20 +1652,20 @@ namespace OpenChams { for (vector::iterator it = nets.begin() ; it != nets.end() ; ++it) { Net* net = (*it); if (net->hasNoConnections()) { - string error("[ERROR] Cannot writeToFile since net ("); - error += net->getName(); - error += ") has no connectors !"; - throw OpenChamsException(error); - //return false; + string error("[ERROR] Cannot writeToFile since net ("); + error += net->getName(); + error += ") has no connectors !"; + throw OpenChamsException(error); + //return false; } if (!net->hasNoPorts() || !net->hasNoWires()) - schematicNets = true; + schematicNets = true; string externStr = (net->isExternal()) ? "True" : "False"; file << " getName() << "\" type=\"" << net->getType() << "\" isExternal=\"" << externStr << "\">" << endl; vector connections = net->getConnections(); sort(connections.begin(), connections.end(), ConnectionsSort); for (vector::iterator it = connections.begin() ; it != connections.end() ; ++it) { - file << " getInstanceName() << "\" name=\"" << (*it)->getConnectorName() << "\"/>" << endl; + file << " getInstanceName() << "\" name=\"" << (*it)->getConnectorName() << "\"/>" << endl; } file << " " << endl; } @@ -1399,119 +1674,119 @@ namespace OpenChams { if (_schematic && !_schematic->hasNoInstances()) { file << " " << endl; for (map::const_iterator it = _schematic->getInstances().begin() ; it != _schematic->getInstances().end(); ++it ) { - Schematic::Infos* infos = (*it).second; - file << " getX() << "\" y=\"" << infos->getY() << "\" orient=\"" << infos->getOrientation() << "\"/>" << endl; + Schematic::Infos* infos = (*it).second; + file << " getX() << "\" y=\"" << infos->getY() << "\" orient=\"" << infos->getOrientation() << "\"/>" << endl; } if (schematicNets) { - for (size_t i = 0 ; i < nets.size() ; i++) { - Net* net = nets[i]; - if (net->hasNoPorts() && net->hasNoWires()) - continue; - file << " getName() << "\">" << endl; - for (size_t j = 0 ; j < net->getPorts().size() ; j++) { - Port* port = net->getPorts()[j]; - if (!port) - continue; - file << " getType() << "\" idx=\"" << port->getIndex() << "\" x=\"" << port->getX() << "\" y=\"" << port->getY() << "\" orient=\"" << port->getOrientation() << "\"/>" << endl; - } - for (size_t j = 0 ; j < net->getWires().size() ; j++) { - Wire* wire = net->getWires()[j]; - file << " " << endl; - WirePoint* start = wire->getStartPoint(); - WirePoint* end = wire->getEndPoint(); - // start point - if (dynamic_cast(start)) { - InstancePoint* iP = static_cast(start); - file << " getName() << "\" plug=\"" << iP->getPlug() << "\"/>" << endl; - } else if (dynamic_cast(start)) { - PortPoint* pP = static_cast(start); - file << " getIndex() << "\"/>" << endl; - } else { - throw OpenChamsException("[ERROR] Wire start point is nor an InstancePoint nor a PortPoint."); - } - // intermediate points - for (size_t k = 0 ; k < wire->getIntermediatePoints().size() ; k++) { - IntermediatePoint* iP = wire->getIntermediatePoints()[k]; - file << " getX() << "\" y=\"" << iP->getY() << "\"/>" << endl; - } - // end point - if (dynamic_cast(end)) { - InstancePoint* iP = static_cast(end); - file << " getName() << "\" plug=\"" << iP->getPlug() << "\"/>" << endl; - } else if (dynamic_cast(end)) { - PortPoint* pP = static_cast(end); - file << " getIndex() << "\"/>" << endl; - } else { - throw OpenChamsException("[ERROR] Wire end point is nor an InstancePoint nor a PortPoint."); - } - file << " " << endl; - } - file << " " << endl; - } + for (size_t i = 0 ; i < nets.size() ; i++) { + Net* net = nets[i]; + if (net->hasNoPorts() && net->hasNoWires()) + continue; + file << " getName() << "\">" << endl; + for (size_t j = 0 ; j < net->getPorts().size() ; j++) { + Port* port = net->getPorts()[j]; + if (!port) + continue; + file << " getType() << "\" idx=\"" << port->getIndex() << "\" x=\"" << port->getX() << "\" y=\"" << port->getY() << "\" orient=\"" << port->getOrientation() << "\"/>" << endl; + } + for (size_t j = 0 ; j < net->getWires().size() ; j++) { + Wire* wire = net->getWires()[j]; + file << " " << endl; + WirePoint* start = wire->getStartPoint(); + WirePoint* end = wire->getEndPoint(); + // start point + if (dynamic_cast(start)) { + InstancePoint* iP = static_cast(start); + file << " getName() << "\" plug=\"" << iP->getPlug() << "\"/>" << endl; + } else if (dynamic_cast(start)) { + PortPoint* pP = static_cast(start); + file << " getIndex() << "\"/>" << endl; + } else { + throw OpenChamsException("[ERROR] Wire start point is nor an InstancePoint nor a PortPoint."); + } + // intermediate points + for (size_t k = 0 ; k < wire->getIntermediatePoints().size() ; k++) { + IntermediatePoint* iP = wire->getIntermediatePoints()[k]; + file << " getX() << "\" y=\"" << iP->getY() << "\"/>" << endl; + } + // end point + if (dynamic_cast(end)) { + InstancePoint* iP = static_cast(end); + file << " getName() << "\" plug=\"" << iP->getPlug() << "\"/>" << endl; + } else if (dynamic_cast(end)) { + PortPoint* pP = static_cast(end); + file << " getIndex() << "\"/>" << endl; + } else { + throw OpenChamsException("[ERROR] Wire end point is nor an InstancePoint nor a PortPoint."); + } + file << " " << endl; + } + file << " " << endl; + } } file << " " << endl; } - // SIZING (modified by Farakh) *************************************************************** + // SIZING (modified by Farakh) *************************************************************** if(_sizing && (!_sizing->hasNoOperators() || !_sizing->hasNoEquations()) ) file << " " << endl; if (_sizing && !_sizing->hasNoOperators()) { - // file << " " << endl; + // file << " " << endl; for (map::const_iterator it = _sizing->getOperators().begin() ; it != _sizing->getOperators().end() ; ++it) { - Operator* op = (*it).second; - string opName = op->getName(); - transform(opName.begin(), opName.end(), opName.begin(), ::toupper); - file << " getSimulModel() << "\">" << endl; - if (!op->hasNoConstraints()) { - for (map::const_iterator cit = op->getConstraints().begin() ; cit != op->getConstraints().end() ; ++cit) { - Operator::Constraint* cn = (*cit).second; - const std::string& ref = cn->getRef(); - if (ref.empty()) { - file << " getRefParam() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; - } else { - file << " getRef() << "\" refParam=\"" << cn->getRefParam() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; - } - } - } - file << " " << endl; + Operator* op = (*it).second; + string opName = op->getName(); + transform(opName.begin(), opName.end(), opName.begin(), ::toupper); + file << " getSimulModel() << "\">" << endl; + if (!op->hasNoConstraints()) { + for (map::const_iterator cit = op->getConstraints().begin() ; cit != op->getConstraints().end() ; ++cit) { + Operator::Constraint* cn = (*cit).second; + const std::string& ref = cn->getRef(); + if (ref.empty()) { + file << " getRefParam() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; + } else { + file << " getRef() << "\" refParam=\"" << cn->getRefParam() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; + } + } + } + file << " " << endl; } } - // EQUATIONS + // EQUATIONS if (_sizing && !_sizing->hasNoEquations()) { file << " " << endl; - // for (map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) - // file << " " << endl; + // for (map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) + // file << " " << endl; file << " " << endl; for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { - if(dynamic_cast((*it).second)) - file << " getEquationStr()[0] << "\"/>" << endl; + if(dynamic_cast((*it).second)) + file << " getEquationStr()[0] << "\"/>" << endl; } file << " " << endl; file << " " << endl; for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { - if(dynamic_cast((*it).second)) - file << " getEquationStr()[0] << "\"/>" << endl; + if(dynamic_cast((*it).second)) + file << " getEquationStr()[0] << "\"/>" << endl; } file << " " << endl; file << " " << endl; for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { - if(dynamic_cast((*it).second)) { - NRCCstr* nrcCstr = (NRCCstr*)((*it).second); - file << " getVoltage() << "\" equation=\"" << (*it).second->getEquationStr()[0] << "\"/>" << endl; - } + if(dynamic_cast((*it).second)) { + NRCCstr* nrcCstr = (NRCCstr*)((*it).second); + file << " getVoltage() << "\" equation=\"" << (*it).second->getEquationStr()[0] << "\"/>" << endl; + } } file << " " << endl; file << " " << endl; for(map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { - if(dynamic_cast((*it).second)) { - file << " " << endl; - for(map::const_iterator it2 = (*it).second->getEquationStr().begin(); it2!=(*it).second->getEquationStr().end(); ++it2) - file << " " << endl; - file << " " << endl; - } + if(dynamic_cast((*it).second)) { + file << " " << endl; + for(map::const_iterator it2 = (*it).second->getEquationStr().begin(); it2!=(*it).second->getEquationStr().end(); ++it2) + file << " " << endl; + file << " " << endl; + } } file << " " << endl; @@ -1520,22 +1795,29 @@ namespace OpenChams { } if(_sizing && (!_sizing->hasNoOperators() || !_sizing->hasNoEquations()) ) file << " " << endl; - // ******************************************************************************************* - + // ******************************************************************************************* if (_layout) { file << " " << endl; if (!_layout->hasNoInstance()) { - for (map::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) { - file << " " << endl; - } + 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; + driveHBTree(file, root, 3); + file << " " << endl; } file << " " << endl; } + // ******************************************************************************************* + + if (_slicingtree) { + driveSlicingTree(file, _slicingtree, 1); + } + + + file << "" << endl; file.close(); return true; diff --git a/vlsisapd/src/openChams/src/SlicingTree.cpp b/vlsisapd/src/openChams/src/SlicingTree.cpp new file mode 100644 index 00000000..6453a7ff --- /dev/null +++ b/vlsisapd/src/openChams/src/SlicingTree.cpp @@ -0,0 +1,1088 @@ + +// -*- C++ -*- +// +// This file is part of the VLSI SAPD Software. +// Copyright (c) UPMC/LIP6 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | V L S I S A P D | +// | OpenChams Circuit Data Base | +// | | +// | Author : Eric Lao | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./SlicingTree.cpp" | +// +-----------------------------------------------------------------+ + + +#include "vlsisapd/openChams/SlicingTree.h" + +using namespace std; + +namespace OpenChams { + +// -----------------------------------------------------------------------------------------------// +// Class : SlicingNode +// -----------------------------------------------------------------------------------------------// + + + void printList( list liste ) + { + for ( list::const_iterator it = liste.begin(); it != liste.end(); it++ ){ + (*it)->print(); + } + } + + SlicingNode::SlicingNode( SlicingNode* parent ) + { + _parent = parent; + _alignment = UnknownAlignment; + } + + + void SlicingNode::setParent ( SlicingNode* parent ) + { + _parent = parent; + } + + + SlicingNode* SlicingNode::getParent () const + { + return _parent; + } + + + void SlicingNode::setAlignment ( std::string alignment ) + { + if (!_parent){ + if ( alignment == "AlignRight" ){ _alignment = AlignRight ; } + else if ( alignment == "AlignLeft" ){ _alignment = AlignLeft ; } + else if ( alignment == "AlignCenter" ){ _alignment = AlignCenter ; } + else if ( alignment == "AlignTop" ){ _alignment = AlignTop ; } + else { _alignment = UnknownAlignment; } + } else { + if (_parent->getType() == HorizontalSNode ){ + if ( alignment == "AlignRight" ){ _alignment = AlignRight ; } + else if ( alignment == "AlignCenter" ){ _alignment = AlignCenter ; } + else { _alignment = AlignLeft ; } + } else if ( _parent->getType() == VerticalSNode ){ + if ( alignment == "AlignCenter" ){ _alignment = AlignCenter ; } + else if ( alignment == "AlignTop" ){ _alignment = AlignTop ; } + else { _alignment = AlignBottom ; } + } else { _alignment = UnknownAlignment; } + } + } + + + string SlicingNode::alignmentToString () const + { + string salignment = ""; + if ( _alignment == AlignRight ){ salignment = "AlignRight" ; } + else if ( _alignment == AlignLeft ){ salignment = "AlignLeft" ; } + else if ( _alignment == AlignCenter ){ salignment = "AlignCenter" ; } + else if ( _alignment == AlignTop ){ salignment = "AlignTop" ; } + else { salignment = "UnknownAlignment"; } + return salignment; + } + + + bool SlicingNode::checkInitialPlacement( int& cpt ) const + { + bool initialPlacement = false; + if ( cpt < 2 ){ initialPlacement = true; } + return initialPlacement; + } + + + list SlicingNode::getLeaves() const + { + return list(); + } + + +// Error Methods + std::string SlicingNode::getInstanceName () const + { + cerr << "Error(std::string SlicingNode::getInstanceName ()): Instance name is used in Device only." << endl; + return ""; + } + + + unsigned int SlicingNode::getAlignment () const + { + cerr << "Error(unsigned int SlicingNode::getAlignment ()): No Alignment in Routing Node." << endl; + return UnknownAlignment; + } + + + bool SlicingNode::getPreset () const + { + cerr << "Error(bool SlicingNode::getPreset ()): Preset is used in Device only." << endl; + return false; + } + + + double SlicingNode::getX () const + { + cerr << "Error(double SlicingNode::getX ()): X is used in Device only." << endl; + return 0; + } + + + double SlicingNode::getY () const + { + cerr << "Error(double SlicingNode::getY ()): Y is used in Device only." << endl; + return 0; + } + + + int SlicingNode::getNFing () const + { + cerr << "Error(int SlicingNode::getNFing ()): Nfing is used in Device only." << endl; + return 1; + } + + + double SlicingNode::getStart () const + { + cerr << "Error(double SlicingNode::getStart ()): Start is used in Device only." << endl; + return 0; + } + + + double SlicingNode::getStep () const + { + cerr << "Error(double SlicingNode::getStep ()): Step is used in Device only." << endl; + return 0; + } + + + double SlicingNode::getCount () const + { + cerr << "Error(double SlicingNode::getCount ()): Step is used in Device only." << endl; + return 0; + } + + + void SlicingNode::setInstanceName ( std::string instanceName ) + { + cerr << "Error(void SlicingNode::setInstanceName ( std::string instanceName )): Instance name is used in Device only." << endl; + } + + + void SlicingNode::setPreset ( std::string preset ) + { + cerr << "Error(void SlicingNode::setPreset ( std::string preset )): Preset is used in Device only." << endl; + } + + + void SlicingNode::setX ( std::string x ) + { + cerr << "Error(void SlicingNode::setX ( std::string x )): X is used in Device only." << endl; + } + + + void SlicingNode::setY ( std::string y ) + { + cerr << "Error(void SlicingNode::setY ( std::string y )): Y is used in Device only." << endl; + } + + + void SlicingNode::setNFing ( std::string nfing ) + { + cerr << "Error(void SlicingNode::setNFing ( std::string nfing )): NFing is used in Device only." << endl; + } + + + void SlicingNode::setStart ( std::string start ) + { + cerr << "Error(void SlicingNode::setStart ( std::string start )): Start is used in Device only." << endl; + } + + + void SlicingNode::setStep ( std::string step ) + { + cerr << "Error(void SlicingNode::setStep ( std::string step )): Step is used in Device only." << endl; + } + + + void SlicingNode::setCount ( std::string count ) + { + cerr << "Error(void SlicingNode::setCount ( std::string count )): Count is used in Device only." << endl; + } + + + void SlicingNode::setPreset ( bool preset ) + { + cerr << "Error(void SlicingNode::setPreset ( bool preset )): Preset is used in Device only." << endl; + } + + + void SlicingNode::setX ( double x ) + { + cerr << "Error(void SlicingNode::setX ( double x )): X is used in Device only." << endl; + } + + + void SlicingNode::setY ( double y ) + { + cerr << "Error(void SlicingNode::setY ( double y )): Y is used in Device only." << endl; + } + + + void SlicingNode::setNFing ( int nfing ) + { + cerr << "Error(void SlicingNode::setNFing ( int nfing )): NFing is used in Device only." << endl; + } + + + void SlicingNode::setStart ( double start ) + { + cerr << "Error(void SlicingNode::setStart ( double start )): Start is used in Device only." << endl; + } + + + void SlicingNode::setStep ( double step ) + { + cerr << "Error(void SlicingNode::setStep ( double step )): Step is used in Device only." << endl; + } + + + void SlicingNode::setCount ( double count ) + { + cerr << "Error(void SlicingNode::setCount ( double count )): Count is used in Device only." << endl; + } + + + double SlicingNode::getToleranceRatioH () const + { + cerr << "Error(double SlicingNode::getToleranceRatioH ()): Tolerances are used in Horizontal or Vertical Node only." << endl; + return 0; + } + + + const vector SlicingNode::getChildren () const + { + cerr << "Error(const vector SlicingNode::getChildren () const): Children are used in Horizontal or Vertical Node only." << endl; + return vector(); + } + + + list > SlicingNode::getSymmetries () const + { + cerr << "Error(list > SlicingNode::getSymmetries () const): Symmetries are used in Horizontal or Vertical Node only." << endl; + return list >(); + } + + + double SlicingNode::getToleranceRatioW () const + { + cerr << "Error(double SlicingNode::getToleranceRatioW ()): Tolerances are used in Horizontal or Vertical Node only." << endl; + return 0; + } + + + double SlicingNode::getToleranceBandH () const + { + cerr << "Error(double SlicingNode::getToleranceBandH ()): Tolerances are used in Horizontal or Vertical Node only." << endl; + return 0; + } + + + double SlicingNode::getToleranceBandW () const + { + cerr << "Error(double SlicingNode::getToleranceBandW ()): Tolerances are used in Horizontal or Vertical Node only." << endl; + return 0; + } + + + void SlicingNode::setToleranceRatioH ( std::string value ) + { + cerr << "Error(void SlicingNode::setToleranceRatioH ( std::string value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::setToleranceRatioW ( std::string value ) + { + cerr << "Error(void SlicingNode::setToleranceRatioW ( std::string value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::setToleranceBandH ( std::string value ) + { + cerr << "Error(void SlicingNode::setToleranceBandH ( std::string value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::setToleranceBandW ( std::string value ) + { + cerr << "Error(void SlicingNode::setToleranceBandW ( std::string value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + + } + + + void SlicingNode::setToleranceRatioH ( double value ) + { + cerr << "Error(void SlicingNode::setToleranceRatioH ( double value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::setToleranceRatioW ( double value ) + { + cerr << "Error(void SlicingNode::setToleranceRatioW ( double value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::setToleranceBandH ( double value ) + { + cerr << "Error(void SlicingNode::setToleranceBandH ( double value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::setToleranceBandW ( double value ) + { + cerr << "Error(void SlicingNode::setToleranceBandW ( double value )): Tolerances are used in Horizontal or Vertical Node only." << endl; + + } + + + void SlicingNode::push_back ( SlicingNode* node ) + { + cerr << "Error(void SlicingNode::push_back ( SlicingNode* node )): Children are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::addSymmetry ( std::string source, std::string target ) + { + cerr << "Error(void SlicingNode::addSymmetry ( std::string source, std::string target )): Symmetries are used in Horizontal or Vertical Node only." << endl; + } + + + void SlicingNode::addSymmetry ( int source, int target ) + { + cerr << "Error(void SlicingNode::addSymmetry ( int source, int target )): Symmetries are used in Horizontal or Vertical Node only." << endl; + } + + + double SlicingNode::getValue () const + { + cerr << "Error(double SlicingNode::getValue ()): Value is used in Routing Node only." << endl; + return 0; + } + + + void SlicingNode::setValue ( std::string value ) + { + cerr << "Error(void SlicingNode::setValue ( std::string value )): Value is used in Routing Node only." << endl; + } + + + string SlicingNode::presetToString () const + { + cerr << "Error(string SlicingNode::presetToString () const): Preset is used in Device only." << endl; + return ""; + } + + + string SlicingNode::xToString () const + { + cerr << "Error(string SlicingNode::xToString () const): X is used in Device only." << endl; + return ""; + } + + + string SlicingNode::yToString () const + { + cerr << "Error(string SlicingNode::yToString () const): Y is used in Device only." << endl; + return ""; + } + + + string SlicingNode::nfingToString () const + { + cerr << "Error(string SlicingNode::nfingToString () const): NFing is used in Device only." << endl; + return ""; + } + + + string SlicingNode::startToString () const + { + cerr << "Error(string SlicingNode::startToString () const): Start is used in Device only." << endl; + return ""; + } + + + string SlicingNode::stepToString () const + { + cerr << "Error(string SlicingNode::stepToString () const): Step is used in Device only." << endl; + return ""; + } + + + string SlicingNode::countToString () const + { + cerr << "Error(string SlicingNode::countToString () const): Count is used in Device only." << endl; + return ""; + } + + + string SlicingNode::valueToString () const + { + cerr << "Error(string SlicingNode::valueToString () const): Value is used in Routing Node only." << endl; + return ""; + } + + + string SlicingNode::toleranceRatioHToString () const + { + cerr << "Error(string SlicingNode::toleranceRatioHToString () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return ""; + } + + + string SlicingNode::toleranceRatioWToString () const + { + cerr << "Error(double SlicingNode::getToleranceRatioW ()): Tolerances are used in Horizontal or Vertical Node only." << endl; + return ""; + } + + + string SlicingNode::toleranceBandHToString () const + { + cerr << "Error(string SlicingNode::toleranceBandHToString () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return ""; + } + + + string SlicingNode::toleranceBandWToString () const + { + cerr << "Error(string SlicingNode::toleranceBandWToString () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return ""; + } + + bool SlicingNode::hasSameParentToleranceRatioH () const + { + cerr << "Error(bool SlicingNode::hasSameParentToleranceRatioH () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return false; + } + + + bool SlicingNode::hasSameParentToleranceRatioW () const + { + cerr << "Error(bool SlicingNode::hasSameParentToleranceRatioW () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return false; + } + + + bool SlicingNode::hasSameParentToleranceBandH () const + { + cerr << "Error(bool SlicingNode::hasSameParentToleranceBandH () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return false; + } + + + bool SlicingNode::hasSameParentToleranceBandW () const + { + cerr << "Error(bool SlicingNode::hasSameParentToleranceBandW () const): Tolerances are used in Horizontal or Vertical Node only." << endl; + return false; + } + + +// -----------------------------------------------------------------------------------------------// +// Class : DSlicingNode +// -----------------------------------------------------------------------------------------------// + + + DSlicingNode::DSlicingNode( std::string instanceName, SlicingNode* parent ): SlicingNode(parent) + { + _instanceName = instanceName; + _alignment = UnknownAlignment; + _preset = false; + _x = 0; + _y = 0; + _nfing = 0; + _start = 0; + _step = 0; + _count = 0; + } + + void DSlicingNode::setInstanceName( std::string instanceName ) + { + _instanceName = instanceName; + } + + + void DSlicingNode::setPreset( std::string preset ) + { + if ( preset == "true" ){ _preset = true ; } + else { _preset = false; } + } + + + void DSlicingNode::setX( std::string x ) + { + std::string::size_type sz; + _x = stof(x, &sz); + } + + + void DSlicingNode::setY( std::string y ) + { + std::string::size_type sz; + _y = stof(y, &sz); + } + + + void DSlicingNode::setNFing( std::string nfing ) + { + std::string::size_type sz; + _nfing = stoi(nfing, &sz); + } + + + void DSlicingNode::setStart( std::string start ) + { + std::string::size_type sz; + _start = stod(start, &sz); + } + + + void DSlicingNode::setStep( std::string step ) + { + std::string::size_type sz; + _step = stod(step, &sz); + } + + + void DSlicingNode::setCount( std::string count ) + { + std::string::size_type sz; + _count = stod(count, &sz); + } + + + void DSlicingNode::print() const + { + cerr << "instance : " << _instanceName << endl; + + if (_parent != NULL){ + unsigned int type = _parent->getType(); + if ( type == HorizontalSNode ){ cerr << "Parent : Type: HorizontalSNode" ; } + else if ( type == VerticalSNode ){ cerr << "Parent : Type: VerticalSNode" ; } + else { cerr << "Parent : Type: UnknownType"; } + cerr << ", trh: " << _parent->getToleranceRatioH(); + cerr << ", trw: " << _parent->getToleranceRatioW(); + cerr << ", tbh: " << _parent->getToleranceBandH(); + cerr << ", tbw: " << _parent->getToleranceBandW(); + cerr << endl; + } else { + cerr << "Parent : None " << endl; + } + + if ( _alignment == AlignLeft ){ cerr << "alignment: AlignLeft" << endl; } + else if ( _alignment == AlignRight ){ cerr << "alignment: AlignRight" << endl; } + else if ( _alignment == AlignCenter ){ cerr << "alignment: AlignCenter" << endl; } + else if ( _alignment == AlignTop ){ cerr << "alignment: AlignTop" << endl; } + else if ( _alignment == AlignBottom ){ cerr << "alignment: AlignBottom" << endl; } + else { cerr << "alignment: Unknown" << endl; } + cerr << "preset : " << _preset << endl; + cerr << "x : " << _x << endl; + cerr << "y : " << _y << endl; + cerr << "nfing : " << _nfing << endl; + cerr << "start : " << _start << endl; + cerr << "step : " << _step << endl; + cerr << "count : " << _count << endl; + cerr << "type : Device" << endl; + cerr << endl; + } + + + void DSlicingNode::toXML ( ofstream& file, unsigned indent ) + { + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + if (_preset){ + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + } + + + bool DSlicingNode::checkInitialPlacement ( int& cpt ) const + { + bool initialPlacement = false; + if ( cpt < 2 ){ + if ( (_x == 0) && (_y == 0) ){ + cpt++; + if ( cpt < 2 ) { initialPlacement = true; } + } + else { initialPlacement = true; } + } + return initialPlacement; + } + + +// -----------------------------------------------------------------------------------------------// +// Class : HVSlicingNode +// -----------------------------------------------------------------------------------------------// + + + HVSlicingNode::HVSlicingNode( SlicingNode* parent ): SlicingNode( parent ) + { + _alignment = UnknownAlignment; + _toleranceRatioH = 0; + _toleranceRatioW = 0; + _toleranceBandH = 0; + _toleranceBandW = 0; + _symmetries = list > (); + _children = vector (); + } + + + void HVSlicingNode::setToleranceRatioH( std::string value ) + { + std::string::size_type sz; + _toleranceRatioH = stof(value, &sz); + } + + + void HVSlicingNode::setToleranceRatioW( std::string value ) + { + std::string::size_type sz; + _toleranceRatioW = stof(value, &sz); + } + + + void HVSlicingNode::setToleranceBandH( std::string value ) + { + std::string::size_type sz; + _toleranceBandH = stof(value, &sz); + } + + + void HVSlicingNode::setToleranceBandW( std::string value ) + { + std::string::size_type sz; + _toleranceBandW = stof(value, &sz); + } + + + void HVSlicingNode::setToleranceRatioH( double value ) + { + _toleranceRatioH = value; + } + + + void HVSlicingNode::setToleranceRatioW( double value ) + { + _toleranceRatioW = value; + } + + + void HVSlicingNode::setToleranceBandH( double value ) + { + _toleranceBandH = value; + } + + + void HVSlicingNode::setToleranceBandW( double value ) + { + _toleranceBandW = value; + } + + + void HVSlicingNode::push_back( SlicingNode* node ) + { + if (node != NULL){ + node->setParent(this); + _children.push_back(node); + } + } + + + void HVSlicingNode::addSymmetry( string source, string target ) + { + std::string::size_type sz; + int isource = stoi(source, &sz); + int itarget = stoi(target, &sz); + _symmetries.push_back(pair(isource, itarget)); + } + + + void HVSlicingNode::addSymmetry( int source, int target ) + { + _symmetries.push_back(pair(source, target)); + } + + + void HVSlicingNode::recursiveDestroy() + { + for (std::vector::iterator it = _children.begin(); it != _children.end(); it++){ + (*it)->recursiveDestroy(); + } + delete(this); + } + + + void HVSlicingNode::print() const + { + if ( _alignment == AlignLeft ){ cerr << "alignment: AlignLeft" << endl; } + else if ( _alignment == AlignRight ){ cerr << "alignment: AlignRight" << endl; } + else if ( _alignment == AlignCenter ){ cerr << "alignment: AlignCenter" << endl; } + else if ( _alignment == AlignTop ){ cerr << "alignment: AlignTop" << endl; } + else if ( _alignment == AlignBottom ){ cerr << "alignment: AlignBottom" << endl; } + else { cerr << "alignment: Unknown" << endl; } + cerr << "tRatioH : " << _toleranceRatioH << endl; + cerr << "tRatioW : " << _toleranceRatioW << endl; + cerr << "tBandH : " << _toleranceBandH << endl; + cerr << "tBandW : " << _toleranceBandW << endl; + } + + + bool HVSlicingNode::hasSameParentToleranceRatioH () const + { + bool same = false; + if (_parent){ + same = (_toleranceRatioH == _parent->getToleranceRatioH()); + } + return same; + } + + + bool HVSlicingNode::hasSameParentToleranceRatioW () const + { + bool same = false; + if (_parent){ + same = (_toleranceRatioW == _parent->getToleranceRatioW()); + } + return same; + } + + + bool HVSlicingNode::hasSameParentToleranceBandH () const + { + bool same = false; + if (_parent){ + same = (_toleranceBandH == _parent->getToleranceBandH()); + } + return same; + } + + + bool HVSlicingNode::hasSameParentToleranceBandW () const + { + bool same = false; + if (_parent){ + same = (_toleranceBandW == _parent->getToleranceBandW()); + } + return same; + } + + + bool HVSlicingNode::checkInitialPlacement( int& cpt ) const + { + bool initialPlacement = false; + if (cpt < 2){ + initialPlacement = true; + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if (cpt < 2){ initialPlacement = (*it)->checkInitialPlacement(cpt); } + } + } + return initialPlacement; + } + + + list HVSlicingNode::getLeaves () const + { + list leaves = list(); + for (vector::const_iterator it = _children.begin(); it != _children.end(); it++){ + if ( ((*it)->getType() == DeviceSNode) || ((*it)->getType() == RoutingSNode) ){ + leaves.push_back((*it)); + } else { + leaves.splice(leaves.end(), (*it)->getLeaves()); + } + } + return leaves; + } + + +// -----------------------------------------------------------------------------------------------// +// Class : HSlicingNode +// -----------------------------------------------------------------------------------------------// + + + HSlicingNode::HSlicingNode( SlicingNode* parent ): HVSlicingNode(parent) + { + _alignment = AlignLeft; + } + + + void HSlicingNode::print() const + { + cerr << "type : Horizontal " << endl; + + if (_parent != NULL){ + unsigned int type = _parent->getType(); + if ( type == HorizontalSNode ){ cerr << "Parent : Type: HorizontalSNode" ; } + else if ( type == VerticalSNode ){ cerr << "Parent : Type: VerticalSNode" ; } + else { cerr << "Parent : Type: UnknownType"; } + cerr << ", trh: " << _parent->getToleranceRatioH(); + cerr << ", trw: " << _parent->getToleranceRatioW(); + cerr << ", tbh: " << _parent->getToleranceBandH(); + cerr << ", tbw: " << _parent->getToleranceBandW(); + cerr << endl; + } else { + cerr << "Parent : None " << endl; + } + HVSlicingNode::print(); + + for (list >::const_iterator it1 = _symmetries.begin(); it1 != _symmetries.end(); it1++){ + cerr << "Symmetrie: (" << (*it1).first << " - " << (*it1).second << ")" << endl; + } + cerr << endl; + + for(vector::const_iterator it = _children.begin(); it != _children.end(); it++ ){ + (*it)->print(); + } + cerr << endl; + } + + + void HSlicingNode::toXML ( ofstream& file, unsigned indent ) + { + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + + // Parameters + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + + if (!hasSameParentToleranceRatioH ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + if (!hasSameParentToleranceRatioW ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + if (!hasSameParentToleranceBandH ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + if (!hasSameParentToleranceBandW ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + // Symmetries + if (!_symmetries.empty()){ + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for ( std::list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++ ){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + } + + // Children + if (!_children.empty()){ + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for (std::vector::const_iterator it2 = _children.begin(); it2 != _children.end(); it2++){ + (*it2)->toXML(file, indent+2); + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + } + + +// -----------------------------------------------------------------------------------------------// +// Class : VSlicingNode +// -----------------------------------------------------------------------------------------------// + + + VSlicingNode::VSlicingNode( SlicingNode* parent ): HVSlicingNode(parent) + { + _alignment = AlignBottom; + } + + + void VSlicingNode::print() const + { + cerr << "type : Vertical " << endl; + + if (_parent != NULL){ + unsigned int type = _parent->getType(); + if ( type == HorizontalSNode ){ cerr << "Parent : Type: HorizontalSNode" ; } + else if ( type == VerticalSNode ){ cerr << "Parent : Type: VerticalSNode" ; } + else { cerr << "Parent : Type: UnknownType"; } + cerr << ", trh: " << _parent->getToleranceRatioH(); + cerr << ", trw: " << _parent->getToleranceRatioW(); + cerr << ", tbh: " << _parent->getToleranceBandH(); + cerr << ", tbw: " << _parent->getToleranceBandW(); + cerr << endl; + } else { + cerr << "Parent : None " << endl; + } + HVSlicingNode::print(); + + for (list >::const_iterator it1 = _symmetries.begin(); it1 != _symmetries.end(); it1++){ + cerr << "Symmetrie: (" << (*it1).first << " - " << (*it1).second << ")" << endl; + } + cerr << endl; + + for(vector::const_iterator it = _children.begin(); it != _children.end(); it++ ){ + (*it)->print(); + } + cerr << endl; + } + + + void VSlicingNode::toXML ( ofstream& file, unsigned indent ) + { + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + + // Parameters + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + + if (!hasSameParentToleranceRatioH ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + if (!hasSameParentToleranceRatioW ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + if (!hasSameParentToleranceBandH ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + if (!hasSameParentToleranceBandW ()){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + // Symmetries + if (!_symmetries.empty()){ + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for ( std::list >::const_iterator it = _symmetries.begin(); it != _symmetries.end(); it++ ){ + for (unsigned i = 0 ; i < indent+2 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + } + + // Children + if (!_children.empty()){ + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + + for (std::vector::const_iterator it2 = _children.begin(); it2 != _children.end(); it2++){ + (*it2)->toXML(file, indent+2); + } + + for (unsigned i = 0 ; i < indent+1 ; i++){ file << " "; } + file << "" << endl; + } + + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + } + + +// -----------------------------------------------------------------------------------------------// +// Class : RSlicingNode +// -----------------------------------------------------------------------------------------------// + + + RSlicingNode::RSlicingNode( std::string value, SlicingNode* parent ): SlicingNode(parent) + { + std::string::size_type sz; + _value = stof(value, &sz); + } + + + RSlicingNode::RSlicingNode( double value, SlicingNode* parent ): SlicingNode(parent) + { + _value = value; + } + + + void RSlicingNode::setValue( string value ) + { + std::string::size_type sz; + _value = stof(value, &sz); + } + + + void RSlicingNode::print() const + { + cerr << "type : Routing " << endl; + cerr << "value : " << _value << endl; + cerr << endl; + } + + + void RSlicingNode::toXML ( ofstream& file, unsigned indent ) + { + for (unsigned i = 0 ; i < indent ; i++){ file << " "; } + file << "" << endl; + } + +} // OpenChams namespace diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h index 1f995133..e11469a0 100644 --- a/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/Circuit.h @@ -2,13 +2,14 @@ // -*- C++ -*- // // This file is part of the VLSI SAPD Software. -// Copyright (c) UPMC/LIP6 2009-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2009-2016, All Rights Reserved // // +-----------------------------------------------------------------+ // | V L S I S A P D | // | OpenChams Circuit Data Base | // | | // | Author : Damien Dupuis | +// | Eric Lao | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./vlsisapd/openChams/Circuit.h" | @@ -27,6 +28,7 @@ #include "vlsisapd/openChams/Parameters.h" #include "vlsisapd/openChams/SimulModel.h" +#include "vlsisapd/openChams/SlicingTree.h" namespace OpenChams { @@ -58,6 +60,7 @@ namespace OpenChams { inline Parameters getParameters (); inline void addSubCircuitPath ( std::string ); inline std::vector& getSubCircuitPaths (); + inline SlicingNode* getSlicingTree (); // Mutators. void addSimulModel ( unsigned , SimulModel::Base @@ -69,7 +72,9 @@ namespace OpenChams { Schematic* createSchematic (); Sizing* createSizing (); Layout* createLayout (); + void setSlicingTree ( SlicingNode* slicingtree ); void driveHBTree ( std::ofstream&, Node*, unsigned ); + void driveSlicingTree ( std::ofstream&, SlicingNode*, unsigned ); bool writeToFile ( std::string filePath ); static Circuit* readFromFile ( const std::string filePath ); @@ -112,6 +117,17 @@ namespace OpenChams { void readHBTree ( xmlNode*, Layout* ); Node* readNodeOrBloc ( xmlNode*, Node* parent = NULL ); void setAbsolutePath ( const std::string filePath ); + // Slicingtree related XML methods. + void readSlicingTree ( xmlNode* ); + SlicingNode* readSlicingNode ( xmlNode* xnode, SlicingNode* slicingNode = NULL ); + VSlicingNode* createVerticalSlicingNode ( xmlNode* xnode, SlicingNode* slicingNode = NULL ); + HSlicingNode* createHorizontalSlicingNode ( xmlNode* xnode, SlicingNode* slicingNode = NULL ); + DSlicingNode* createDeviceSlicingNode ( xmlNode* xnode, SlicingNode* slicingNode = NULL ); + RSlicingNode* createRoutingSlicingNode ( xmlNode* xnode, SlicingNode* slicingNode = NULL ); + void addChildren ( xmlNode*, HVSlicingNode* ); + void setHVParameters ( xmlNode*, HVSlicingNode* ); + void setHVSymmetries ( xmlNode*, HVSlicingNode* ); + // Utilities methods. void check_uppercase ( std::string& str, std::vector& compares, std::string message ); void check_lowercase ( std::string& str, std::vector& compares, std::string message ); @@ -127,6 +143,7 @@ namespace OpenChams { Layout* _layout; std::vector _subCircuitsPaths; std::map _simulModels; + SlicingNode* _slicingtree; }; @@ -142,7 +159,7 @@ namespace OpenChams { inline Parameters Circuit::getParameters () { return _params; } inline void Circuit::addSubCircuitPath (std::string path) { _subCircuitsPaths.push_back(path); } inline std::vector& Circuit::getSubCircuitPaths () { return _subCircuitsPaths; } - + inline SlicingNode* Circuit::getSlicingTree () { return _slicingtree; } template inline std::string asString ( T value ) diff --git a/vlsisapd/src/openChams/src/vlsisapd/openChams/SlicingTree.h b/vlsisapd/src/openChams/src/vlsisapd/openChams/SlicingTree.h new file mode 100644 index 00000000..3bcb21ce --- /dev/null +++ b/vlsisapd/src/openChams/src/vlsisapd/openChams/SlicingTree.h @@ -0,0 +1,392 @@ + +// -*- C++ -*- +// +// This file is part of the VLSI SAPD Software. +// Copyright (c) UPMC/LIP6 2008-2016, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | V L S I S A P D | +// | OpenChams Circuit Data Base | +// | | +// | Author : Eric Lao | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./vlsisapd/openChams/SlicingTree.h" | +// +-----------------------------------------------------------------+ + +#ifndef __OPENCHAMS_SLICINGTREE_H__ +#define __OPENCHAMS_SLICINGTREE_H__ + +#include +#include +#include +#include +#include +#include + + +namespace OpenChams { + + enum Flags { UnknownType = 1 << 0 + , HorizontalSNode = 1 << 1 + , VerticalSNode = 1 << 2 + , DeviceSNode = 1 << 3 + , RoutingSNode = 1 << 4 + , UnknownAlignment = 1 << 5 + , AlignLeft = 1 << 6 + , AlignRight = 1 << 7 + , AlignCenter = 1 << 8 + , AlignTop = 1 << 9 + , AlignBottom = 1 << 10 + }; + +// -----------------------------------------------------------------------------------------------// +// Class : SlicingNode +// -----------------------------------------------------------------------------------------------// + + + class SlicingNode + { + public: + SlicingNode( SlicingNode* parent = NULL ); + virtual ~SlicingNode(){}; + + public: + virtual unsigned int getType () const { return UnknownType; } + virtual void print () const {}; + inline void recursiveDestroy (); + void setParent ( SlicingNode* parent ); + SlicingNode* getParent () const; + inline bool isRoot () const; + virtual void setAlignment ( std::string alignment ); + std::string alignmentToString() const; + //Error Methods + virtual std::string getInstanceName () const; + virtual unsigned int getAlignment () const; + virtual bool getPreset () const; + virtual double getX () const; + virtual double getY () const; + virtual int getNFing () const; + virtual double getStart () const; + virtual double getStep () const; + virtual double getCount () const; + + virtual void setInstanceName ( std::string instanceName ); + virtual void setPreset ( std::string preset ); + virtual void setX ( std::string x ); + virtual void setY ( std::string y ); + virtual void setNFing ( std::string nfing ); + virtual void setStart ( std::string start ); + virtual void setStep ( std::string step ); + virtual void setCount ( std::string count ); + + virtual void setPreset ( bool preset ); + virtual void setX ( double x ); + virtual void setY ( double y ); + virtual void setNFing ( int nfing ); + virtual void setStart ( double start ); + virtual void setStep ( double step ); + virtual void setCount ( double count ); + + virtual const std::vector getChildren () const; + virtual std::list > getSymmetries () const; + + virtual double getToleranceRatioH() const; + virtual double getToleranceRatioW() const; + virtual double getToleranceBandH () const; + virtual double getToleranceBandW () const; + + virtual void setToleranceRatioH( std::string value ); + virtual void setToleranceRatioW( std::string value ); + virtual void setToleranceBandH ( std::string value ); + virtual void setToleranceBandW ( std::string value ); + + virtual void setToleranceRatioH( double value ); + virtual void setToleranceRatioW( double value ); + virtual void setToleranceBandH ( double value ); + virtual void setToleranceBandW ( double value ); + + virtual void push_back ( SlicingNode* node ); + virtual void addSymmetry ( std::string source, std::string target ); + virtual void addSymmetry ( int source, int target ); + virtual double getValue () const; + virtual void setValue ( std::string value ); + virtual void toXML ( std::ofstream& file, unsigned indent ){}; + + virtual std::string presetToString () const; + virtual std::string xToString () const; + virtual std::string yToString () const; + virtual std::string nfingToString () const; + virtual std::string startToString () const; + virtual std::string stepToString () const; + virtual std::string countToString () const; + virtual std::string valueToString () const; + + virtual std::string toleranceRatioHToString() const; + virtual std::string toleranceRatioWToString() const; + virtual std::string toleranceBandHToString () const; + virtual std::string toleranceBandWToString () const; + + virtual bool hasSameParentToleranceRatioH () const; + virtual bool hasSameParentToleranceRatioW () const; + virtual bool hasSameParentToleranceBandH () const; + virtual bool hasSameParentToleranceBandW () const; + + virtual bool checkInitialPlacement( int& cpt ) const; + virtual std::list getLeaves () const; + + protected: + SlicingNode* _parent; + unsigned int _alignment; + }; + + inline void SlicingNode::recursiveDestroy(){ delete(this); } + inline bool SlicingNode::isRoot () const { return (_parent == NULL); } + + +// -----------------------------------------------------------------------------------------------// +// Class : DeviceSNode +// -----------------------------------------------------------------------------------------------// + + + class DSlicingNode : public SlicingNode + { + private: + DSlicingNode( std::string instanceName, SlicingNode* parent = NULL ); + ~DSlicingNode(){}; + + public: + inline static DSlicingNode* create ( std::string instanceName, SlicingNode* parent = NULL ); + inline std::string getInstanceName () const; + inline unsigned int getAlignment () const; + inline bool getPreset () const; + inline double getX () const; + inline double getY () const; + inline int getNFing () const; + inline double getStart () const; + inline double getStep () const; + inline double getCount () const; + inline unsigned int getType () const; + + void setInstanceName ( std::string instanceName ); + void setPreset ( std::string preset ); + void setX ( std::string x ); + void setY ( std::string y ); + void setNFing ( std::string nfing ); + void setStart ( std::string start ); + void setStep ( std::string step ); + void setCount ( std::string count ); + + inline void setPreset ( bool preset ); + inline void setX ( double x ); + inline void setY ( double y ); + inline void setNFing ( int nfing ); + inline void setStart ( double start ); + inline void setStep ( double step ); + inline void setCount ( double count ); + + void print () const; + void toXML ( std::ofstream& file, unsigned indent ); + inline std::string presetToString () const; + inline std::string xToString () const; + inline std::string yToString () const; + inline std::string nfingToString () const; + inline std::string startToString () const; + inline std::string stepToString () const; + inline std::string countToString () const; + + bool checkInitialPlacement ( int& cpt ) const; + + private: + std::string _instanceName; + bool _preset; + double _x; + double _y; + int _nfing; + double _start; + double _step; + double _count; + }; + + inline DSlicingNode* DSlicingNode::create ( std::string instanceName, SlicingNode* parent ){ return new DSlicingNode( instanceName ); } + inline std::string DSlicingNode::getInstanceName () const { return _instanceName ; } + inline unsigned int DSlicingNode::getAlignment () const { return _alignment ; } + inline bool DSlicingNode::getPreset () const { return _preset ; } + inline double DSlicingNode::getX () const { return _x ; } + inline double DSlicingNode::getY () const { return _y ; } + inline int DSlicingNode::getNFing () const { return _nfing ; } + inline double DSlicingNode::getStart () const { return _start ; } + inline double DSlicingNode::getStep () const { return _step ; } + inline double DSlicingNode::getCount () const { return _count ; } + inline unsigned int DSlicingNode::getType () const { return DeviceSNode ; } + + inline void DSlicingNode::setPreset ( bool preset ) { _preset = preset; } + inline void DSlicingNode::setX ( double x ) { _x = x ; } + inline void DSlicingNode::setY ( double y ) { _y = y ; } + inline void DSlicingNode::setNFing ( int nfing ) { _nfing = nfing ; } + inline void DSlicingNode::setStart ( double start ) { _start = start ; } + inline void DSlicingNode::setStep ( double step ) { _step = step ; } + inline void DSlicingNode::setCount ( double count ) { _count = count ; } + + inline std::string DSlicingNode::presetToString () const { return _preset ? "true" : "false"; } + inline std::string DSlicingNode::xToString () const { return std::to_string(_x ); } + inline std::string DSlicingNode::yToString () const { return std::to_string(_y ); } + inline std::string DSlicingNode::nfingToString () const { return std::to_string(_nfing); } + inline std::string DSlicingNode::startToString () const { return std::to_string(_start); } + inline std::string DSlicingNode::stepToString () const { return std::to_string(_step ); } + inline std::string DSlicingNode::countToString () const { return std::to_string(_count); } + +// -----------------------------------------------------------------------------------------------// +// Class : HVSlicingNode +// -----------------------------------------------------------------------------------------------// + + + class HVSlicingNode : public SlicingNode + { + protected: + HVSlicingNode( SlicingNode* parent = NULL ); + virtual ~HVSlicingNode(){}; + + public: + inline unsigned int getAlignment () const; + inline double getToleranceRatioH() const; + inline double getToleranceRatioW() const; + inline double getToleranceBandH () const; + inline double getToleranceBandW () const; + inline const std::vector getChildren () const; + inline std::list > getSymmetries () const; + + void setToleranceRatioH( std::string value ); + void setToleranceRatioW( std::string value ); + void setToleranceBandH ( std::string value ); + void setToleranceBandW ( std::string value ); + + void setToleranceRatioH( double value ); + void setToleranceRatioW( double value ); + void setToleranceBandH ( double value ); + void setToleranceBandW ( double value ); + + void push_back ( SlicingNode* node ); + void addSymmetry ( std::string source, std::string target ); + void addSymmetry ( int source, int target ); + void recursiveDestroy (); + void print () const; + + inline std::string toleranceRatioHToString () const; + inline std::string toleranceRatioWToString () const; + inline std::string toleranceBandHToString () const; + inline std::string toleranceBandWToString () const; + + bool hasSameParentToleranceRatioH () const; + bool hasSameParentToleranceRatioW () const; + bool hasSameParentToleranceBandH () const; + bool hasSameParentToleranceBandW () const; + + bool checkInitialPlacement ( int& cpt ) const; + std::list getLeaves () const; + + protected: + double _toleranceRatioH; + double _toleranceRatioW; + double _toleranceBandH; + double _toleranceBandW; + std::list > _symmetries; + std::vector _children; + }; + + inline unsigned int HVSlicingNode::getAlignment () const { return _alignment ; } + inline double HVSlicingNode::getToleranceRatioH() const { return _toleranceRatioH; } + inline double HVSlicingNode::getToleranceRatioW() const { return _toleranceRatioW; } + inline double HVSlicingNode::getToleranceBandH () const { return _toleranceBandH ; } + inline double HVSlicingNode::getToleranceBandW () const { return _toleranceBandW ; } + inline const std::vector HVSlicingNode::getChildren () const { return _children ; } + inline std::list > HVSlicingNode::getSymmetries () const { return _symmetries ; } + + inline std::string HVSlicingNode::toleranceRatioHToString() const { return std::to_string(_toleranceRatioH); } + inline std::string HVSlicingNode::toleranceRatioWToString() const { return std::to_string(_toleranceRatioW); } + inline std::string HVSlicingNode::toleranceBandHToString () const { return std::to_string(_toleranceBandH); } + inline std::string HVSlicingNode::toleranceBandWToString () const { return std::to_string(_toleranceBandW); } + + +// -----------------------------------------------------------------------------------------------// +// Class : HSlicingNode +// -----------------------------------------------------------------------------------------------// + + + class HSlicingNode: public HVSlicingNode + { + private: + HSlicingNode( SlicingNode* parent = NULL ); + ~HSlicingNode(){}; + + public: + inline static HSlicingNode* create ( SlicingNode* parent = NULL ); + inline unsigned int getType () const; + void print () const; + void toXML ( std::ofstream& file, unsigned indent ); + }; + + inline HSlicingNode* HSlicingNode::create ( SlicingNode* parent ){ return new HSlicingNode(parent); } + inline unsigned int HSlicingNode::getType() const { return HorizontalSNode ; } + + +// -----------------------------------------------------------------------------------------------// +// Class : VSlicingNode +// -----------------------------------------------------------------------------------------------// + + + class VSlicingNode: public HVSlicingNode + { + private: + VSlicingNode( SlicingNode* parent = NULL ); + ~VSlicingNode(){}; + + public: + inline static VSlicingNode* create ( SlicingNode* parent = NULL ); + inline unsigned int getType () const; + void print () const; + void toXML ( std::ofstream& file, unsigned indent ); + }; + + inline VSlicingNode* VSlicingNode::create ( SlicingNode* parent ){ return new VSlicingNode(parent); } + inline unsigned int VSlicingNode::getType() const { return VerticalSNode ; } + + +// -----------------------------------------------------------------------------------------------// +// Class : RoutingSNode +// -----------------------------------------------------------------------------------------------// + + + class RSlicingNode: public SlicingNode + { + private: + RSlicingNode( std::string value, SlicingNode* parent = NULL ); + RSlicingNode( double value, SlicingNode* parent = NULL ); + ~RSlicingNode(){}; + + public: + inline static RSlicingNode* create ( std::string value, SlicingNode* parent = NULL ); + inline static RSlicingNode* create ( double value, SlicingNode* parent = NULL ); + inline void recursiveDestroy (); + inline double getValue () const; + void setValue ( std::string value ); + inline unsigned int getType () const; + void print () const; + void setAlignment ( std::string alignment) {}; + void toXML ( std::ofstream& file, unsigned indent ); + inline std::string valueToString () const; + + private: + double _value; + }; + + inline RSlicingNode* RSlicingNode::create ( std::string value, SlicingNode* parent ){ return new RSlicingNode( value, parent ); } + inline RSlicingNode* RSlicingNode::create ( double value, SlicingNode* parent ){ return new RSlicingNode( value, parent ); } + inline double RSlicingNode::getValue () const{ return _value ; } + inline unsigned int RSlicingNode::getType () const{ return RoutingSNode; } + inline std::string RSlicingNode::valueToString () const { return std::to_string(_value); } + + +} // OpenChams namespace + +#endif