Adding support for Layout section in openChams parser/driver

This commit is contained in:
Damien Dupuis 2010-09-02 10:30:02 +00:00
parent c2f3a393f1
commit 76820567a7
8 changed files with 155 additions and 3 deletions

View File

@ -10,6 +10,7 @@ SET ( hpps vlsisapd/openChams/Circuit.h
vlsisapd/openChams/Schematic.h
vlsisapd/openChams/SimulModel.h
vlsisapd/openChams/Sizing.h
vlsisapd/openChams/Layout.h
vlsisapd/openChams/Transistor.h
vlsisapd/openChams/OpenChamsException.h
)
@ -23,6 +24,7 @@ SET ( cpps Circuit.cpp
Schematic.cpp
SimulModel.cpp
Sizing.cpp
Layout.cpp
Transistor.cpp
)
SET ( pycpps PyOpenChams.cpp

View File

@ -21,6 +21,7 @@ using namespace std;
#include "vlsisapd/openChams/Schematic.h"
#include "vlsisapd/openChams/SimulModel.h"
#include "vlsisapd/openChams/Sizing.h"
#include "vlsisapd/openChams/Layout.h"
#include "vlsisapd/openChams/Transistor.h"
#include "vlsisapd/openChams/Operator.h"
#include "vlsisapd/openChams/OpenChamsException.h"
@ -44,8 +45,9 @@ static bool readInstancesDone = false;
static bool readNetsDone = false;
static bool readSchematicDone = false;
static bool readSizingDone = false;
static bool readLayoutDone = false;
Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL) {
Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlist(NULL), _schematic(NULL), _sizing(NULL), _layout(NULL) {
readCircuitParametersDone = false;
readSimulModelsDone = false;
readNetListDone = false;
@ -53,6 +55,7 @@ Circuit::Circuit(Name name, Name techno) : _name(name), _techno(techno), _netlis
readNetsDone = false;
readSchematicDone = false;
readSizingDone = false;
readLayoutDone = false;
}
// COMPARISON FUNCTION //
@ -641,6 +644,40 @@ void Circuit::readEquation(xmlNode* node, Sizing* sizing) {
}
}
// LAYOUT //
void Circuit::readLayout(xmlNode* node) {
if (readLayoutDone) {
cerr << "[WARNING] Only one 'layout' node is allowed in circuit, others will be ignored." << endl;
return;
}
Layout* layout = new Layout(this);
xmlNode* child = node->children;
for (xmlNode* node = child; node; node = node->next) {
if (node->type == XML_ELEMENT_NODE) {
if (xmlStrEqual(node->name, (xmlChar*)"instance")) {
readInstanceLayout(node, layout);
} else {
cerr << "[WARNING] Only 'instance' nodes are allowed in 'sizing', others will be ignored." << endl;
}
}
}
readLayoutDone = true;
_layout = layout;
}
void Circuit::readInstanceLayout(xmlNode* node, Layout* layout) {
xmlChar* nameC = xmlGetProp(node, (xmlChar*)"name");
xmlChar* styleC = xmlGetProp(node, (xmlChar*)"style");
if (nameC && styleC) {
Name iName ((const char*)nameC);
Name styleName ((const char*)styleC);
layout->addInstance(iName, styleName);
} else {
throw OpenChamsException("[ERROR] 'instance' node in 'layout' must have 'name' and 'style' properties.");
}
}
Circuit* Circuit::readFromFile(const string filePath) {
LIBXML_TEST_VERSION;
Circuit* cir = NULL;
@ -684,6 +721,9 @@ Circuit* Circuit::readFromFile(const string filePath) {
else if (xmlStrEqual(node->name, (xmlChar*)"sizing")) {
cir->readSizing(node);
}
else if (xmlStrEqual(node->name, (xmlChar*)"layout")) {
cir->readLayout(node);
}
else {
string error("[ERROR] Unknown section ");
error += string((const char*)node->name);
@ -733,6 +773,17 @@ Sizing* Circuit::createSizing() {
return _sizing;
}
Layout* Circuit::createLayout() {
if (_layout)
throw OpenChamsException("[ERROR] Cannot create two layouts in one circuit.");
_layout = new Layout(this);
if (!_layout)
throw OpenChamsException("[ERROR] Cannot create layout.");
return _layout;
}
bool Circuit::writeToFile(string filePath) {
ofstream file;
file.open(filePath.c_str());
@ -874,6 +925,13 @@ bool Circuit::writeToFile(string filePath) {
}
file << " </sizing>" << endl;
}
if (_layout && !_layout->hasNoInstance()) {
file << " <layout>" << endl;
for (map<Name, Name>::const_iterator it = _layout->getInstances().begin() ; it != _layout->getInstances().end() ; ++it) {
file << " <instance name=\"" << ((*it).first).getString() << "\" style=\"" << ((*it).second).getString() << "\"/>" << endl;
}
file << " </layout>" << endl;
}
file << "</circuit>" << endl;
file.close();
return true;

View File

@ -0,0 +1,32 @@
/*
* Layout.cpp
* openChams
*
* Created by damien dupuis on 31/08/10.
* Copyright 2008-2010 UPMC / LIP6. All rights reserved.
*
*/
#include <string>
using namespace std;
#include "vlsisapd/openChams/Layout.h"
#include "vlsisapd/openChams/Circuit.h"
#include "vlsisapd/openChams/OpenChamsException.h"
namespace OpenChams {
Layout::Layout(Circuit* circuit): _circuit(circuit) {}
void Layout::addInstance(Name name, Name style) {
map<Name, Name>::iterator it = _instances.find(name);
if (it != _instances.end()) {
string error("[ERROR] Cannot set several instances with the same name in 'layout' (");
error += name.getString();
error += ").";
throw OpenChamsException(error);
}
_instances[name] = style;
}
} // namespace

View File

@ -14,6 +14,7 @@ using namespace boost::python;
#include "vlsisapd/openChams/Operator.h"
#include "vlsisapd/openChams/SimulModel.h"
#include "vlsisapd/openChams/Sizing.h"
#include "vlsisapd/openChams/Layout.h"
#include "vlsisapd/openChams/Circuit.h"
#include "vlsisapd/openChams/OpenChamsException.h"
@ -238,6 +239,18 @@ BOOST_PYTHON_MODULE(OPENCHAMS) {
.def("getOperators", &Sizing::getOperators, return_internal_reference<>())
;
// map wrapping for OpenChams::Layout
STL_MAP_WRAPPING(Name, Name, "LayoutInstancesMap")
// class OpenChams::Layout
class_<Layout, Layout*>("Layout", init<Circuit*>())
// accessors
.def("hasNoInstance", &Layout::hasNoInstance)
// modifiers
.def("addInstance", &Layout::addInstance)
// stl containers
.def("getInstances", &Layout::getInstances, return_internal_reference<>())
;
class_<Circuit, Circuit*>("Circuit", init<Name, Name>())
// properties
.add_property("name" , &Circuit::getName )
@ -246,12 +259,14 @@ BOOST_PYTHON_MODULE(OPENCHAMS) {
.add_property("netlist" , make_function(&Circuit::getNetlist , return_value_policy<reference_existing_object>()))
.add_property("schematic" , make_function(&Circuit::getSchematic, return_value_policy<reference_existing_object>()))
.add_property("sizing" , make_function(&Circuit::getSizing , return_value_policy<reference_existing_object>()))
.add_property("layout" , make_function(&Circuit::getLayout , return_value_policy<reference_existing_object>()))
// accessors
.def("getValue", &Circuit::getValue)
// modifiers
.def("createNetlist" , &Circuit::createNetlist , return_value_policy<reference_existing_object>())
.def("createSchematic", &Circuit::createSchematic, return_value_policy<reference_existing_object>())
.def("createSizing" , &Circuit::createSizing , return_value_policy<reference_existing_object>())
.def("createLayout" , &Circuit::createLayout , return_value_policy<reference_existing_object>())
.def("addParameter", static_cast<void(Circuit::*)(Name, double )>(&Circuit::addParameter))
.def("addParameter", static_cast<void(Circuit::*)(Name, std::string)>(&Circuit::addParameter))
// others

View File

@ -28,6 +28,7 @@ class Schematic;
class Sizing;
class Transistor;
class Operator;
class Layout;
class Circuit {
public:
@ -39,6 +40,7 @@ class Circuit {
inline Netlist* getNetlist();
inline Schematic* getSchematic();
inline Sizing* getSizing();
inline Layout* getLayout();
inline void addParameter(Name, double);
inline void addParameter(Name, std::string);
inline Parameters getParameters();
@ -46,10 +48,12 @@ class Circuit {
void addSimulModel(unsigned, SimulModel::Base, SimulModel::Version, std::string);
inline void setSizing(Sizing*);
inline void setLayout(Layout*);
Netlist* createNetlist();
Schematic* createSchematic(double);
Sizing* createSizing();
Layout* createLayout();
bool writeToFile(std::string filePath);
static Circuit* readFromFile(const std::string filePath);
@ -78,6 +82,8 @@ class Circuit {
void readConstraint(xmlNode*, Operator*);
void readEquations(xmlNode*, Sizing*);
void readEquation(xmlNode*, Sizing*);
void readLayout(xmlNode*);
void readInstanceLayout(xmlNode*, Layout*);
void check_uppercase(std::string& str, std::vector<std::string>& compares, std::string message);
void check_lowercase(std::string& str, std::vector<std::string>& compares, std::string message);
@ -88,6 +94,7 @@ class Circuit {
Netlist* _netlist;
Schematic* _schematic;
Sizing* _sizing;
Layout* _layout;
std::map<unsigned, SimulModel*> _simulModels;
};
@ -97,6 +104,7 @@ inline double Circuit::getValue(Name name) { return _params.getValue(name);
inline Netlist* Circuit::getNetlist() { return _netlist; };
inline Schematic* Circuit::getSchematic() { return _schematic; };
inline Sizing* Circuit::getSizing() { return _sizing; };
inline Layout* Circuit::getLayout() { return _layout; };
inline void Circuit::addParameter(Name name, double value) { _params.addParameter(name, value); };
inline void Circuit::addParameter(Name name, std::string eqStr) { _params.addParameter(name, eqStr); };
inline Parameters Circuit::getParameters() { return _params; };

View File

@ -0,0 +1,37 @@
/*
* Layout.h
* openChams
*
* Created by damien dupuis on 31/08/10.
* Copyright 2008-2010 UPMC / LIP6. All rights reserved.
*
*/
#ifndef __OPENCHAMS_LAYOUT_H__
#define __OPENCHAMS_LAYOUT_H__
#include <map>
namespace OpenChams {
class Name;
class Circuit;
class Layout {
public:
Layout(Circuit*);
void addInstance(Name name, Name style);
inline bool hasNoInstance();
inline const std::map<Name, Name>& getInstances();
private:
Circuit* _circuit;
std::map<Name, Name> _instances; // device name <-> style (name)
};
inline bool Layout::hasNoInstance() { return (_instances.size() == 0) ? true : false; };
inline const std::map<Name, Name>& Layout::getInstances() { return _instances; };
} // namespace
#endif

View File

@ -3,7 +3,7 @@
* openChams
*
* Created by damien dupuis on 18/12/09.
* Copyright 2009 UPMC / LIP6. All rights reserved.
* Copyright 2008-2010 UPMC / LIP6. All rights reserved.
*
*/

View File

@ -1,5 +1,5 @@
/*
* SchematicInfos.h
* Schematic.h
* openChams
*
* Created by damien dupuis on 22/01/10.