diff --git a/vlsisapd/examples/liberty/python/CMakeLists.txt b/vlsisapd/examples/liberty/python/CMakeLists.txt new file mode 100644 index 00000000..2860108b --- /dev/null +++ b/vlsisapd/examples/liberty/python/CMakeLists.txt @@ -0,0 +1 @@ +INSTALL ( FILES parseLiberty.py driveLiberty.py DESTINATION share/doc/coriolis2/examples/vlsisapd/liberty ) diff --git a/vlsisapd/examples/liberty/python/driveLiberty.py b/vlsisapd/examples/liberty/python/driveLiberty.py new file mode 100644 index 00000000..f6b26a71 --- /dev/null +++ b/vlsisapd/examples/liberty/python/driveLiberty.py @@ -0,0 +1,47 @@ +from LIBERTY import * + +library = Library("test") + +# Attributes +library.addAttribute("default_inout_pin_cap", Attribute.Type.Double, "0.011") +library.addAttribute("default_wire_load_mode", Attribute.Type.String, "enclosed") +library.addAttribute("time_unit", Attribute.Type.Unit, "1", "ns") +library.addAttribute("capacitive_load_unit", Attribute.Type.Unit, "1", "pf") + +# WireLoads +library.addWireLoad("medium") +wireLoad = library.getWireLoad("medium") +wireLoad.addAttribute("slope", Attribute.Type.Double, "200") +wireLoad.addAttribute("fanout_length", Attribute.Type.Pair, "1", "200") + +# WireLoadSelection +library.addWireLoadSelection("medium") +wireLoadSelection = library.getWireLoadSelection() +wireLoadSelection.addWireLoadArea(0, 500, "small") + +# Cells +library.addCell("inv") +cell = library.getCell("inv") +cell.addAttribute("area", Attribute.Type.Double, "1") +cell.addAttribute("cell_footprint", Attribute.Type.String, "inv") + +# Pins +cell.addPin("e") +pin = cell.getPin("e") +pin.addAttribute("direction", Attribute.Type.String, "input") +pin.addAttribute("capacitance", Attribute.Type.Double, "0.008") + +cell.addPin("s") +pin = cell.getPin("s") +pin.addAttribute("direction", Attribute.Type.String, "output") +pin.addAttribute("function", Attribute.Type.String, "i'") + +# Timing +pin.addTiming() +timing = pin.getTimings()[-1] +timing.addAttribute("timing_sense", Attribute.Type.String, "negative_unate") +timing.addAttribute("related_pin", Attribute.Type.String, "e") +timing.addAttribute("intrinsic_rise", Attribute.Type.Double, "0.101") + +# Write +library.writeToFile("testDrive.lib") diff --git a/vlsisapd/examples/liberty/python/parseLiberty.py b/vlsisapd/examples/liberty/python/parseLiberty.py new file mode 100644 index 00000000..77132bc1 --- /dev/null +++ b/vlsisapd/examples/liberty/python/parseLiberty.py @@ -0,0 +1,13 @@ +from LIBERTY import * + +library = Library.readFromFile("./testParse.lib") + +if ( library ) : + # print of the library + library.pprint() + # print of one attribute in particular + print "| area of inv_x1= ", library.getCell("inv_x1").getAttribute("area").valueAsString() + print "| timing intrinsic_rise of nq of inv_x1= ", library.getCell("inv_x1").getPin("nq").getTiming("i").getAttribute("intrinsic_rise").valueAsString() +else : + raise ( "library is NULL" ) + diff --git a/vlsisapd/src/liberty/src/PyLiberty.cpp b/vlsisapd/src/liberty/src/PyLiberty.cpp new file mode 100644 index 00000000..c037c5da --- /dev/null +++ b/vlsisapd/src/liberty/src/PyLiberty.cpp @@ -0,0 +1,228 @@ +using namespace std; + +#include +#include +using namespace boost::python; + +#include "vlsisapd/liberty/Name.h" +#include "vlsisapd/liberty/Attribute.h" +#include "vlsisapd/liberty/WireLoad.h" +#include "vlsisapd/liberty/WireLoadArea.h" +#include "vlsisapd/liberty/WireLoadSelection.h" +#include "vlsisapd/liberty/Cell.h" +#include "vlsisapd/liberty/Pin.h" +#include "vlsisapd/liberty/Timing.h" +#include "vlsisapd/liberty/FlipFlop.h" +#include "vlsisapd/liberty/Library.h" + +#include "vlsisapd/liberty/PySTLMapWrapper.h" + +namespace LIB { +//void translator(LibertyException const& e) { +// PyErr_SetString(PyExc_UserWarning, e.what()); +//} + +// specify that Techno::addRule method has optional arguments +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(addAttribute_overloads, addAttribute, 3, 4); + +BOOST_PYTHON_MODULE(LIBERTY) { + // class Liberty::Name + ////////////////////// + class_("Name", init()) + // accessors + .def("getString", &Name::getString, return_value_policy()) // return_value_policy because this method return a reference on string + .def("__repr__" , &Name::getString, return_value_policy()) // automatic print for Name object + // operators + .def(self == self) + .def(self == std::string()) + .def(self < self) + ; + + implicitly_convertible(); + + // class Liberty::Attribute + /////////////////////////// + { + scope attrib = class_("Attribute", init()) + // properties + .add_property("name", &Attribute::getName) // no setter => readonly + .add_property("type", &Attribute::getType) // no setter => readonly + .add_property("unit", make_function(&Attribute::getUnit, return_value_policy())) // no setter => readonly // return reference + // accessors + .def("valueAsString", &Attribute::valueAsString, return_value_policy()) // return reference + .def("secondValueAsString", &Attribute::secondValueAsString, return_value_policy()) // return reference + .def("valueAsBool", &Attribute::valueAsBool) + .def("valueAsInt", &Attribute::valueAsInt) + .def("valueAsDouble", &Attribute::valueAsDouble) + .def("secondValueAsDouble", &Attribute::secondValueAsDouble) + .def("typeToString", &Attribute::typeToString) + // miscellaneous + .def("write", &Attribute::write) + ; + + enum_("Type") + .value("Unknown", Attribute::Unknown) + .value("String" , Attribute::String ) + .value("Bool" , Attribute::Bool ) + .value("Int" , Attribute::Int ) + .value("Double" , Attribute::Double ) + .value("Unit" , Attribute::Unit ) + .value("Pair" , Attribute::Pair ) +// .export_values() + ; + } + + // map wrapping + STL_MAP_WRAPPING_PTR(Name, Attribute*, "AttributesMap") + STL_MAP_WRAPPING_PTR(Name, WireLoad*, "WiresLoadMap") + STL_MAP_WRAPPING_PTR(Name, Cell*, "CellsMap") + STL_MAP_WRAPPING_PTR(Name, Pin*, "PinsMap") + + class_ >("WiresLoadAreaVector") + .def(vector_indexing_suite, true>()) + ; + + class_ >("TimingsVector") + .def(vector_indexing_suite, true>()) + ; + + // class Liberty::WireLoad + ////////////////////////// + class_("WireLoad", init()) + // properties + .add_property("name", &WireLoad::getName) // no setter => readonly + // accessors + .def("getAttributes", &WireLoad::getAttributes, return_internal_reference<>()) + .def("getAttribute", &WireLoad::getAttribute, return_value_policy()) + // modifiers + .def("addAttribute", &WireLoad::addAttribute, addAttribute_overloads()) + // miscellaneous + .def("pprint", &WireLoad::print) + .def("write", &WireLoad::write) + ; + + // class Liberty::WireLoadArea + ////////////////////////////// + class_("WireLoadArea", init()) + // properties + .add_property("min", &WireLoadArea::getMin) // no setter => readonly + .add_property("max", &WireLoadArea::getMax) // no setter => readonly + .add_property("name", &WireLoadArea::getName) // no setter => readonly + // miscellaneous + .def("write", &WireLoad::write) + ; + + // class Liberty::WireLoadSelection + /////////////////////////////////// + class_("WireLoadSelection", init()) + // properties + .add_property("name", &WireLoadSelection::getName) // no setter => readonly + // accessors + .def("getWiresLoadArea", &WireLoadSelection::getWiresLoadArea, return_internal_reference<>()) + // modifiers + .def("addWireLoadArea", &WireLoadSelection::addWireLoadArea) + // miscellaneous + .def("pprint", &WireLoadSelection::print) + .def("write", &WireLoadSelection::write) + ; + + // class Liberty::Cell + ////////////////////// + class_("Cell", init()) + // properties + .add_property("name", &Cell::getName) // no setter => readonly + // accessors + .def("getAttributes", &Cell::getAttributes, return_internal_reference<>()) + .def("getPins", &Cell::getPins, return_internal_reference<>()) + .def("getAttribute", &Cell::getAttribute, return_value_policy()) + .def("getPin", &Cell::getPin, return_value_policy()) + .def("getFF", &Cell::getFF, return_value_policy()) + .def("getTestCell", &Cell::getTestCell, return_value_policy()) + // modifiers + .def("addAttribute", &Cell::addAttribute) + .def("addPin", &Cell::addPin) + .def("addFF", &Cell::addFF) + .def("setTestCell", &Cell::setTestCell) + // miscellaneous + .def("pprint", &Cell::print) + .def("write", &Cell::write) + ; + + // class Liberty::Pin + ///////////////////// + class_("Pin", init()) + // properties + .add_property("name", &Pin::getName) // no setter => readonly + // accessors + .def("getAttributes", &Pin::getAttributes, return_internal_reference<>()) + .def("getTimings", &Pin::getTimings, return_internal_reference<>()) + .def("getAttribute", &Pin::getAttribute, return_value_policy()) + .def("getTiming", &Pin::getTiming, return_value_policy()) + // modifiers + .def("addAttribute", &Pin::addAttribute) + .def("addTiming", &Pin::addTiming) + // miscellaneous + .def("pprint", &Pin::print) + .def("write", &Pin::write) + ; + + // class Liberty::Timing + //////////////////////// + class_("Timing", init<>()) + // accessors + .def("getAttributes", &Timing::getAttributes, return_internal_reference<>()) + .def("getAttribute", &Timing::getAttribute, return_value_policy()) + // modifiers + .def("addAttribute", &Timing::addAttribute) + // miscellaneous + .def("pprint", &Timing::print) + .def("write", &Timing::write) + ; + + // class Liberty::FlipFlop + ////////////////////////// + class_("FlipFlop", init()) + // properties + .add_property("noninverting", &FlipFlop::getNonInverting) // no setter => readonly + .add_property("inverting", &FlipFlop::getInverting) // no setter => readonly + // accessors + .def("getAttributes", &FlipFlop::getAttributes, return_internal_reference<>()) + .def("getAttribute", &FlipFlop::getAttribute, return_value_policy()) + // modifiers + .def("addAttribute", &FlipFlop::addAttribute) + // miscellaneous + .def("pprint", &FlipFlop::print) + .def("write", &FlipFlop::write) + ; + + // class Liberty::Library + ///////////////////////// + class_("Library", init()) + // properties + .add_property("name", &Library::getName) // no setter => readonly + // accessors + .def("getAttributes", &Library::getAttributes, return_internal_reference<>()) + .def("getWiresLoad", &Library::getWiresLoad, return_internal_reference<>()) + .def("getCells", &Library::getCells, return_internal_reference<>()) + .def("getAttribute", &Library::getAttribute, return_value_policy()) + .def("getWireLoad", &Library::getWireLoad, return_value_policy()) + .def("getCell", &Library::getCell, return_value_policy()) + .def("getWireLoadSelection", &Library::getWireLoadSelection, return_value_policy()) + // modifiers + .def("addAttribute", &Library::addAttribute, addAttribute_overloads()) + .def("addWireLoad", &Library::addWireLoad) + .def("addWireLoadSelection", &Library::addWireLoadSelection) + .def("addCell", &Library::addCell) + // miscellaneous + .def("pprint", &Library::print ) // "print" does not work in Python + .def("readFromFile", &Library::readFromFile, return_value_policy()) + .staticmethod("readFromFile") + .def("writeToFile", &Library::writeToFile) + ; + + + // LibertyException translator +// register_exception_translator(translator) +// ; +} +}