/* * Circuit.cpp * openChams * * Created by damien dupuis on 18/12/09. * Copyright 2009 UPMC / LIP6. All rights reserved. * */ #include #include #include #include #include using namespace std; #include "Circuit.h" #include "OpenChamsException.h" namespace { template T getValue(xmlChar* str) { std::istringstream iss; iss.str((const char*) str); T res; iss >> res; return res; } } namespace OpenChams { static bool readCircuitParametersDone = false; static bool readNetListDone = false; static bool readInstancesDone = false; static bool readNetsDone = false; static bool readSchematicDone = false; static bool readSizingDone = false; Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL) { readCircuitParametersDone = false; readNetListDone = false; readInstancesDone = false; readNetsDone = false; readSchematicDone = false; readSizingDone = false; } // USEFUL // void Circuit::check_uppercase(string& str, vector& compares, string message) { transform(str.begin(), str.end(), str.begin(), ::toupper); bool equal = false; for (size_t i = 0 ; i < compares.size() ; i++) { if (str == compares[i]) { equal = true; } } if (!equal) { throw OpenChamsException(message); } } void Circuit::check_lowercase(string& str, vector& compares, string message) { transform(str.begin(), str.end(), str.begin(), ::tolower); bool equal = false; for (size_t i = 0 ; i < compares.size() ; i++) { if (str == compares[i]) { equal = true; } } if (!equal) { throw OpenChamsException(message); } } Name Circuit::readParameter(xmlNode* node, double& value) { xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* valueC = xmlGetProp(node, (xmlChar*)"value"); if (paramNameC && valueC) { Name name((const char*)paramNameC); value = ::getValue(valueC); return name; } else { throw OpenChamsException("[ERROR] 'parameter' node must have 'name' and 'value' properties."); } } Name Circuit::readParameterEq(xmlNode* node, string& eqStr) { xmlChar* paramNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* equationC = xmlGetProp(node, (xmlChar*)"equation"); if (paramNameC && equationC) { Name name((const char*)paramNameC); eqStr = string ((const char*)equationC); return name; } else { throw OpenChamsException("[ERROR] 'parameterEq' node must have 'name' and 'equation' properties."); } } Name Circuit::readConnector(xmlNode* node) { xmlChar* connectorNameC = xmlGetProp(node, (xmlChar*)"name"); if (connectorNameC) { Name name((const char*)connectorNameC); return name; } else { throw OpenChamsException("[ERROR] 'connector' node must have 'name' property."); //return Name(""); } } // CIRCUIT // void Circuit::readCircuitParameters(xmlNode* node) { if (readCircuitParametersDone) { cerr << "[WARNING] Only one 'parameters' node is allowed in circuit, others will be ignored." << endl; return; } if (node->type == XML_ELEMENT_NODE && node->children) { for (xmlNode* paramNode = node->children ; paramNode ; paramNode = paramNode->next) { if (paramNode->type == XML_ELEMENT_NODE) { if (xmlStrEqual(paramNode->name, (xmlChar*)"parameter")) { double value = 0.0; Name paramName = readParameter(paramNode, value); if (paramName == Name("")) return; // error addParameter(paramName, value); } else if (xmlStrEqual(paramNode->name, (xmlChar*)"parameterEq")) { string eqStr = ""; Name paramName = readParameterEq(paramNode, eqStr); if (paramName == Name("")) return; // error addParameter(paramName, eqStr); } else { cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'parameters' node." << endl; return; } } } } readCircuitParametersDone = true; } // NETLIST // void Circuit::readNetList(xmlNode* node) { if (readNetListDone) { cerr << "[WARNING] Only one 'netlist' node is allowed in circuit, others will be ignored." << endl; return; } Netlist* netlist = new Netlist(this); xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"instances")) { readInstances(node, netlist); } else if (xmlStrEqual(node->name, (xmlChar*)"nets")) { readNets(node, netlist); } else { cerr << "[WARNING] Only 'instances' and 'nets' nodes are allowed in 'netlist', others will be ignored." << endl; } } } readNetListDone = true; _netlist = netlist; } // INSTANCES // void Circuit::readInstances(xmlNode* node, Netlist* netlist) { if (readInstancesDone) { cerr << "[WARNING] Only one 'instances' node is allowed in 'netlist', others will be ignored." << endl; return; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"instance")) { Instance* inst =readInstance(node, netlist); if (inst) netlist->addInstance(inst); } else { cerr << "[WARNING] Only 'instance' nodes are allowed in 'instances', others will be ignored." << endl; } } } readInstancesDone = true; } Instance* Circuit::readInstance(xmlNode* node, Netlist* netlist) { xmlChar* iNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* iModelC = xmlGetProp(node, (xmlChar*)"model"); xmlChar* iMOSC = xmlGetProp(node, (xmlChar*)"mostype"); xmlChar* iSBCC = xmlGetProp(node, (xmlChar*)"sourceBulkConnected"); Instance* inst = NULL; if (iNameC && iModelC && iMOSC && iSBCC) { Name instanceName((const char*)iNameC); Name modelName((const char*)iModelC); string mosStr((const char*)iMOSC); string mosComp[2] = {"NMOS", "PMOS"}; vector mosComps (mosComp, mosComp+2); check_uppercase(mosStr, mosComps, "[ERROR] In 'instance', 'mostype' must be 'NMOS' or 'PMOS'."); string sourceBulkStr((const char*)iSBCC); string sbcComp[4] = {"true", "false", "on", "off"}; vector sbcComps(sbcComp, sbcComp+4); check_lowercase(sourceBulkStr, sbcComps, "[ERROR] In 'instance', 'sourceBulkConnected' must 'true', 'false', 'on' or 'off'."); bool sourceBulkConnected = ((sourceBulkStr == "true") || (sourceBulkStr == "on")) ? true : false; inst = new Instance(instanceName, modelName, Name(mosStr), sourceBulkConnected, netlist); } else { throw OpenChamsException("[ERROR] 'instance' node must have 'name', 'model', 'mostype' and 'sourceBulkConnected' properties."); //return inst; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"connectors")) { readInstanceConnectors(node, inst); } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { readInstanceParameters(node, inst); } else if (xmlStrEqual(node->name, (xmlChar*)"transistors")) { readInstanceTransistors(node, inst); } else { //cerr << "[WARNING] Only 'parameters' node is allowed in 'instance', others will be ignored." << endl; cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; } } } return inst; } void Circuit::readInstanceConnectors(xmlNode* node, Instance* inst) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"connector")) { Name connectorName = readConnector(node); if (connectorName == Name("")) return; // error inst->addConnector(connectorName); } } } } void Circuit::readInstanceParameters(xmlNode* node, Instance* inst) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"parameter")) { double value = 0.0; Name paramName = readParameter(node, value); if (paramName == Name("")) return; // error inst->addParameter(paramName, value); } else if (xmlStrEqual(node->name, (xmlChar*)"parameterEq")) { string eqStr = ""; Name paramName = readParameterEq(node, eqStr); if (paramName == Name("")) return; // error inst->addParameter(paramName, eqStr); } else { cerr << "[WARNING] Only 'parameter' and 'parameterEq' nodes are allowed under 'instance' node." << endl; return; } } } } void Circuit::readInstanceTransistors(xmlNode* node, Instance* inst) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"transistor")) { readTransistor(node, inst); } else { cerr << "[WARNING] Only 'transistor' nodes are allowed in 'transistors', others will be ignored." << endl; } } } } void Circuit::readTransistor(xmlNode* node, Instance* inst) { xmlChar* tNameC = xmlGetProp(node, (xmlChar*)"name"); Transistor* trans = NULL; if (tNameC) { Name tName((const char*)tNameC); trans = new Transistor(tName, inst); } else { throw OpenChamsException("[ERROR] 'transistor' node must have 'name' property."); //return inst; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"connection")) { readTransistorConnection(node, trans); } else if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { cerr << "Transistor parameters NOT SUPPORTED YET" << endl; } else { cerr << "[WARNING] Only 'conectors', 'transistors' and 'parameters' nodes are allowed in 'instance', others will be ignored." << endl; } } } inst->addTransistor(trans); } void Circuit::readTransistorConnection(xmlNode* node, Transistor* trans) { xmlChar* gateC = xmlGetProp(node, (xmlChar*)"gate"); xmlChar* sourceC = xmlGetProp(node, (xmlChar*)"source"); xmlChar* drainC = xmlGetProp(node, (xmlChar*)"drain"); xmlChar* bulkC = xmlGetProp(node, (xmlChar*)"bulk"); if (gateC && sourceC && drainC && bulkC) { Name gateN ((const char*)gateC); Name sourceN((const char*)sourceC); Name drainN ((const char*)drainC); Name bulkN ((const char*)bulkC); trans->setGate(gateN); trans->setSource(sourceN); trans->setDrain(drainN); trans->setBulk(bulkN); } else { throw OpenChamsException("[ERROR] 'connection' node must have 'gate', 'source', 'drain' and 'bulk' properties."); } } // NETS // void Circuit::readNets(xmlNode* node, Netlist* netlist) { if (readNetsDone) { cerr << "[WARNING] Only one 'nets' node is allowed in 'netlist', others will be ignored." << endl; return; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"net")) { readNet(node, netlist); } else { cerr << "[WARNING] Only 'net' nodes are allowed in 'nets', others will be ignored." << endl; } } } readNetsDone = true; } Net* Circuit::readNet(xmlNode* node, Netlist* netlist) { xmlChar* nNameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* nTypeC = xmlGetProp(node, (xmlChar*)"type"); xmlChar* nExternC = xmlGetProp(node, (xmlChar*)"isExternal"); Net* net = NULL; if (nNameC && nTypeC && nExternC) { Name netName((const char*)nNameC); string typeStr((const char*)nTypeC); string typeComp[3] = {"power", "ground", "logical"}; vector typeComps(typeComp, typeComp+3); check_lowercase(typeStr, typeComps, "[ERROR] In 'net', 'type' must be 'power', 'ground' or 'logical'."); string externStr((const char*)nExternC); string extComp[4] = {"true", "false", "on", "off"}; vector extComps(extComp, extComp+4); check_lowercase(externStr, extComps, "[ERROR] In 'net', 'isExternal' must be 'true', 'false', 'on' or 'off'."); bool isExternal = ((externStr == "true") || (externStr == "on")) ? true : false; net = new Net(netName, Name(typeStr), isExternal, netlist); netlist->addNet(net); } else { throw OpenChamsException("[ERROR] 'net' node must have 'name', 'type' and 'isExternal' properties."); //return net; } xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"connector")) { readNetConnector(node, net); } else { cerr << "[WARNING] Only 'conector' nodes are allowed in 'net', others will be ignored." << endl; return NULL; } } } return net; } void Circuit::readNetConnector(xmlNode* node, Net* net) { xmlChar* instanceNameC = xmlGetProp(node, (xmlChar*)"instance"); xmlChar* connectorNameC = xmlGetProp(node, (xmlChar*)"name"); if (instanceNameC && connectorNameC) { Name iName((const char*)instanceNameC); Name cName((const char*)connectorNameC); Instance* inst = net->getNetlist()->getInstance(iName); if (!inst) { string error("[ERROR] no instance named \""); error += iName.getString(); error += "\" in connector of net \""; error += net->getName().getString(); error += "\"."; throw OpenChamsException(error); //return; } //inst->connect(cName, net->getName()); net->connectTo(iName, cName); } else { throw OpenChamsException("[ERROR] 'connector' node must have 'instance' and 'name' properties (for net)."); } } // SCHEMATIC // void Circuit::readSchematic(xmlNode* node) { if (readSchematicDone) { cerr << "[WARNING] Only one 'schematic' node is allowed in circuit, others will be ignored." << endl; return; } xmlChar* zoomC = xmlGetProp(node, (xmlChar*)"zoom"); double zoom = 1.0; if (zoomC) { zoom = ::getValue(zoomC); } else { throw OpenChamsException("[ERROR] 'schematic' node must have 'zoom' property."); } Schematic* schematic = new Schematic(this, zoom); xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"instance")) { readInstanceSchematic(node, schematic); } else { cerr << "[WARNING] Only 'instance' nodes are allowed in 'schematic', others will be ignored." << endl; } } } readSchematicDone = true; _schematic = schematic; } void Circuit::readInstanceSchematic(xmlNode* node, Schematic* schematic) { xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* xC = xmlGetProp(node, (xmlChar*)"x"); xmlChar* yC = xmlGetProp(node, (xmlChar*)"y"); xmlChar* symC = xmlGetProp(node, (xmlChar*)"sym"); if (nameC && xC && yC && symC) { Name iName((const char*)nameC); double x = ::getValue(xC); double y = ::getValue(yC); string symStr((const char*)symC); string symComp[8] = {"ID", "R1", "R2", "R3", "MX", "XR", "MY", "YR"}; vector symComps (symComp, symComp+8); check_uppercase(symStr, symComps, "[ERROR] In 'schematic/instance', 'sym' must be 'ID', 'R1', 'R2', 'R3', 'MX', 'XR', 'MY' or 'YR'."); schematic->addInstance(iName, x, y, Name(symStr)); } else { throw OpenChamsException("[ERROR] 'instance' node in 'schematic' must have 'name', 'x', 'y' and 'sym' properties."); } } // SIZING // void Circuit::readSizing(xmlNode* node) { if (readSizingDone) { cerr << "[WARNING] Only one 'sizing' node is allowed in circuit, others will be ignored." << endl; return; } Sizing* sizing = new Sizing(this); xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"instance")) { readInstanceSizing(node, sizing); } else if (xmlStrEqual(node->name, (xmlChar*)"equations")) { readEquations(node, sizing); } else { cerr << "[WARNING] Only 'instance' and 'equations' nodes are allowed in 'sizing', others will be ignored." << endl; } } } readSizingDone = true; _sizing = sizing; } void Circuit::readInstanceSizing(xmlNode* node, Sizing* sizing) { xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* operatorC = xmlGetProp(node, (xmlChar*)"operator"); xmlChar* simulModC = xmlGetProp(node, (xmlChar*)"simulModel"); xmlChar* orderC = xmlGetProp(node, (xmlChar*)"callOrder"); if (nameC && operatorC && simulModC && orderC) { Name iName ((const char*)nameC); Name opName ((const char*)operatorC); Name simulMod((const char*)simulModC); unsigned callOrder = ::getValue(orderC); Operator* op = sizing->addOperator(iName, opName, simulMod, callOrder); xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"constraint")) { readConstraint(node, op); } else { cerr << "[WARNING] Only 'constraint' nodes are allowed in 'instance' of 'sizing', others will be ignored." << endl; } } } } else { throw OpenChamsException("[ERROR] 'instance' node in 'sizing' must have 'name', 'operator', 'simulModel' and 'callOrder' properties."); } } void Circuit::readConstraint(xmlNode* node, Operator* op) { // attributes of constraint may be : // param ref refParam [factor] // param refEquation [factor] xmlChar* paramC = xmlGetProp(node, (xmlChar*)"param"); xmlChar* refC = xmlGetProp(node, (xmlChar*)"ref"); xmlChar* refParamC = xmlGetProp(node, (xmlChar*)"refParam"); xmlChar* refEqC = xmlGetProp(node, (xmlChar*)"refEquation"); xmlChar* factorC = xmlGetProp(node, (xmlChar*)"factor"); if (paramC && refC && refParamC) { Name param ((const char*)paramC); Name ref ((const char*)refC); Name refParam ((const char*)refParamC); double factor = 1.0; if (factorC) { factor = ::getValue(factorC); } op->addConstraint(param, ref, refParam, factor); } else if (paramC && refEqC) { Name param ((const char*)paramC); Name refEq ((const char*)refEqC); double factor = 1.0; if (factorC) { factor = ::getValue(factorC); } op->addConstraint(param, refEq, factor); } else { throw OpenChamsException("[ERROR] 'constraint' node must have 'param, ref, refParam, [factor]' or 'param, refEq, [factor]' properties."); } } void Circuit::readEquations(xmlNode* node, Sizing* sizing) { xmlNode* child = node->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"eq")) { readEquation(node, sizing); } else { throw OpenChamsException("[ERROR] Only 'eq' nodes are allowed in 'equations'."); } } } } void Circuit::readEquation(xmlNode* node, Sizing* sizing) { xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name"); xmlChar* equationC = xmlGetProp(node, (xmlChar*)"equation"); if (nameC && equationC) { Name eName ((const char*)nameC); string eqStr ((const char*)equationC); sizing->addEquation(eName, eqStr); } else { throw OpenChamsException("[ERROR] 'eq' node in 'equations' must have 'name' and 'equation' properties."); } } Circuit* Circuit::readFromFile(const string filePath) { LIBXML_TEST_VERSION; Circuit* cir = NULL; xmlDoc* doc = xmlReadFile(filePath.c_str(), NULL, 0); if (doc == NULL) { string error ("[ERROR] Failed to parse: "); error += filePath; throw OpenChamsException(error); //return NULL; } xmlNode* rootElement = xmlDocGetRootElement(doc); if (rootElement->type == XML_ELEMENT_NODE && xmlStrEqual(rootElement->name, (xmlChar*)"circuit")) { xmlChar* circuitNameC = xmlGetProp(rootElement, (xmlChar*)"name"); xmlChar* technoNameC = xmlGetProp(rootElement, (xmlChar*)"techno"); if (circuitNameC && technoNameC) { Name circuitName ((const char*)circuitNameC); Name technoName ((const char*)technoNameC); cir = new Circuit(circuitName, technoName); } else { throw OpenChamsException("[ERROR] 'circuit' node must have 'name' and 'techno' properties."); return NULL; } xmlNode* child = rootElement->children; for (xmlNode* node = child; node; node = node->next) { if (node->type == XML_ELEMENT_NODE) { if (xmlStrEqual(node->name, (xmlChar*)"parameters")) { cir->readCircuitParameters(node); } if (xmlStrEqual(node->name, (xmlChar*)"netlist")) { cir->readNetList(node); } if (xmlStrEqual(node->name, (xmlChar*)"schematic")) { cir->readSchematic(node); } if (xmlStrEqual(node->name, (xmlChar*)"sizing")) { cir->readSizing(node); } } } } if (!readNetListDone) { throw OpenChamsException("[ERROR] no section was found in parsed file !"); } return cir; } 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."; throw OpenChamsException(error); } // checks before do anything if (!_netlist) { //cerr << "no netlist" << endl; cerr.flush(); throw OpenChamsException("[ERROR] Cannot writeToFile since no netlist is defined !"); //return false; } if (_netlist->hasNoInstances()) { //cerr << "no instances" << endl; cerr.flush(); throw OpenChamsException("[ERROR] Cannot writeToFile since no instance is defined in netlist !"); //return false; } if (_netlist->hasNoNets()) { //cerr << "no nets" << endl; cerr.flush(); throw OpenChamsException("[ERROR] Cannot writeToFile since no net is defined in netlist !"); //return false; } file << "" << endl << "" << endl; if (!_params.isEmpty()) { file << " " << endl; for (map::const_iterator it = _params.getValues().begin() ; it != _params.getValues().end() ; ++it) { file << " " << endl; } for (map::const_iterator it = _params.getEqValues().begin() ; it != _params.getEqValues().end() ; ++it) { file << " " << endl; } file << " " << endl; } file << " " << endl << " " << endl; for (vector::const_iterator it = _netlist->getInstances().begin() ; it != _netlist->getInstances().end() ; ++it) { Instance* inst = (*it); if (inst->hasNoConnectors()) { string error("[ERROR] Cannot writeToFile since instance ("); error += inst->getName().getString(); error += ") has no connectors !"; throw OpenChamsException(error); //return false; } if (inst->hasNoTransistors()) { string error("[ERROR] Cannot writeToFile since instance ("); error += inst->getName().getString(); error += ") has no transistors !"; throw OpenChamsException(error); } string sourceBulkStr = (inst->isSourceBulkConnected()) ? "True" : "False"; file << " getName().getString() << "\" model=\"" << inst->getModel().getString() << "\" mostype=\"" << inst->getMosType().getString() << "\" sourceBulkConnected=\"" << sourceBulkStr << "\">" << endl; file << " " << endl; for (map::const_iterator it = inst->getConnectors().begin() ; it != inst->getConnectors().end() ; ++it) { file << " " << endl; } file << " " << endl << " " << endl; for (vector::const_iterator it = inst->getTransistors().begin() ; it != inst->getTransistors().end() ; ++it ) { Transistor* tr = (*it); file << " getName().getString() << "\">" << endl << " getGate().getString() << "\" source=\"" << tr->getSource().getString() << "\" drain=\"" << tr->getDrain().getString() << "\" bulk=\"" << tr->getBulk().getString() << "\"/>" << 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; } file << " " << endl; } file << " " << endl << " " << endl; for (vector::const_iterator it = _netlist->getNets().begin() ; it != _netlist->getNets().end() ; ++it) { Net* net = (*it); if (net->hasNoConnectors()) { string error("[ERROR] Cannot writeToFile since net ("); error += net->getName().getString(); error += ") has no connectors !"; throw OpenChamsException(error); //return false; } string externStr = (net->isExternal()) ? "True" : "False"; file << " getName().getString() << "\" type=\"" << net->getType().getString() << "\" isExternal=\"" << externStr << "\">" << endl; for (vector >::const_iterator it = net->getConnections().begin() ; it != net->getConnections().end() ; ++it) { file << " " << endl; } file << " " << endl; } file << " " << endl; file << " " << endl; if (_schematic && !_schematic->hasNoInstances()) { file << " getZoom() << "\">" << endl; for (map::const_iterator it = _schematic->getInstances().begin() ; it != _schematic->getInstances().end(); ++it ) { Schematic::Infos* infos = (*it).second; file << " getX() << "\" y=\"" << infos->getY() << "\" sym=\"" << infos->getSymetry().getString() << "\"/>" << endl; } file << " " << endl; } if (_sizing && !_sizing->hasNoOperators()) { file << " " << endl; for (map::const_iterator it = _sizing->getOperators().begin() ; it != _sizing->getOperators().end() ; ++it) { Operator* op = (*it).second; file << " getName().getString() << "\" simulModel=\"" << op->getSimulModel().getString() << "\" callOrder=\"" << op->getCallOrder() << "\">" << endl; if (!op->hasNoConstraints()) { for (map::const_iterator cit = op->getConstraints().begin() ; cit != op->getConstraints().end() ; ++cit) { Operator::Constraint* cn = (*cit).second; Name ref = cn->getRef(); if (ref == Name("")) { file << " getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; } else { file << " getRef().getString() << "\" refParam=\"" << cn->getRefParam().getString() << "\" factor=\"" << cn->getFactor() << "\"/>" << endl; } } } file << " " << endl; } if (!_sizing->hasNoEquations()) { file << " " << endl; for (map::const_iterator it = _sizing->getEquations().begin() ; it != _sizing->getEquations().end() ; ++it) { file << " " << endl; } file << " " << endl; } file << " " << endl; } file << "" << endl; file.close(); return true; } }