Adding support for Layout section in openChams parser/driver
This commit is contained in:
parent
c2f3a393f1
commit
76820567a7
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SchematicInfos.h
|
||||
* Schematic.h
|
||||
* openChams
|
||||
*
|
||||
* Created by damien dupuis on 22/01/10.
|
||||
|
|
Loading…
Reference in New Issue