An Introduction to Openaccess Scripting
Total Page:16
File Type:pdf, Size:1020Kb
An Introduction to OpenAccess Scripting James D. Masters Intel Corp Design Automation Conference June 6, 2011 1 What is it? • Standalone direct interface to OpenAccess (OA) – No dependencies beyond OA and no licensing fees – Performance and memory usage is good for a scripting language • Matches C++ API with some melding to native language features – Existing C++ API documentation can be referenced – Auto conversions to/from native types (e.g. strings, integers, floats) • Includes convenience functions to reduce code and improve productivity – More natural interface; e.g. native array of (1.234, 9.876) instead of oaPoint(1234, 9876) 2 How does it work? Perl API Python API Ruby API Tcl API C# API Language-Specific Bindings Type Mapping Type Mapping Type Mapping Type Mapping Type Mapping Common Wrapper Architecture Interface Common SWIG Framework OA API C++ Programming Interface • Common interface through SWIG ensures cross-language consistency and reuse • All languages interface OA through the official OA API 3 Basic type mapping • Some basic OA types are mapped to native types in the target language Perl Python Ruby Tcl C# oaBoolean integer bool Boolean integer bool oa*Int integer int Fixnum integer int, uint, long,ulong oaFloat/Double Float float Float float float/double oaString string string String string string oaArray array array Array list IList<T> oaTime oaTime oaTime Time oaTime DateTime oaTimestamp integer int Fixnum integer uint oaComplex oaComplex complex OaComplex oaComplex oaComplex oaPoint oaPoint/array oaPoint/array OaPoint/Array oaPoint/list oaPoint oaBox oaBox/array oaBox/array OaBox/Array oaBox/list oaBox oaTransform oaTransform/ oaTransform/ OaTransform/ oaTransform/ oaTransform array array Array list 4 Input string / scalarName values • All oaScript languages allow a native string to be used in place of an oaScalarName C++ oaNativeNS nns(); oaString str("mylib"); oaScalarName sname(nns, str); oaLib *lib = oaLib::find(sname); Perl $lib = oaLib::find("mylib"); Python lib = oaLib.find("mylib") Ruby lib = OaLib.find("mylib") Tcl set lib [oaLib_find mylib] C# oaLib lib = oaLib.find("mylib"); 5 Mapping to OA API documentation • Similar syntax to the C++ API Static Public Methods oaLib * oaLib::create (const oaScalarName &name, const oaString &libPath, oaLibMode mode=oacSharedLibMode, const oaString &dmSystem="oaDMSystem", const oaDMAttrArray *dmAttrList=NULL) Perl oa::oaLib::create(oaScalarName|string, string, oaLibMode, string, array|undef) Python oa.oaLib.create(oaScalarName|string, oaString, oaLibMode, oaString, array|None) Ruby Oa::OaLib.create(oaScalarName|String, String, oaLibMode|symbol, String, Array|nil) Tcl oa::oaLib_create oaScalarName|string string|oaLibMode string list|"NULL" C# OpenAccess_4.oaLib.create(oaScalarName|string, string, oaLibMode, string, oaDMAttrArray) 6 Mapping to OA API documentation • Sample documentation map to target language Public Methods oaBoolean getAccess (oaLibAccess accessType, oaUInt4 timeout=0) Perl $lib->getAccess(new oa::oaLibAccess('read')); $lib->getAccess($oa::oacReadLibAccess); Python lib.getAccess(oa.oaLibAccess('read')) lib.getAccess(oa.oaLibAccess(oa.oacReadLibAccess)) Ruby lib.getAccess(Oa::OaLibAccess.new('read')) lib.getAccess(Oa::OaLibAccess.new(Oa::OacReadLibAccess)) lib.getAccess(:read) Tcl $lib getAccess [oa::oaLibAccess "read"] $lib getAccess [oa::oaLibAccess $oa::oacReadLibAccess] $lib getAccess $oa::oacReadLibAccess C# lib.getAccess(oaLibAccess.oacReadLibAccess); 7 Enumerated wrappers • Enumerated wrappers (e.g. oaLibMode) are mapped differently in each language Perl Input: Integer Output: Integer Python Input: Wrapped object, integer, or string Output: Wrapped object (can cast to integer value with “__int__”) Ruby Input: Wrapped object, integer, or string Output: Wrapped object (can cast to integer value with “to_i” or string with “to_s”) Tcl Input: Wrapped object or integer Output: Wrapped object (can cast to integer value with “$enumWrapper typeEnum”) C# Input: Native C# enum Output: Native C# enum Note: all languages have the enum constants available (e.g. oacReadLibAccess) 8 Collections / Iterators • Map collections/iterators natively in target language; allow native loops when possible Perl $iter = new oa::oaIter::oaNet($block->getNets()); while ($net = $iter->getNext()) { ... } Python for net in block.getNets(): ... Ruby block.getNets.each do |net| ... end Tcl oa::foreach net [$block getNets] { ... } C# foreach(oaNet net in block.getNets()) { ... } 9 Unique behaviors • For safety, all languages except C# check for validity of an OA object first using oaObject::isValid() • Return strings, oaPoint, oaBox, and oaArray instead of requiring pre-allocation (example in Tcl): puts [$net getName] set boxlist [$fig getBBox] • Override default name space used in oaName type of conversions (example in Ruby): Oa::OaNameSpace.push(Oa::OaCdbaNS.new) # ... Default NS is OaCdbaNS in this section Oa::OaNameSpace.pop 10 C++: Dump Nets #include <iostream> #include "oaDesignDB.h" int main( int argc, char *argv[] ) { oa::oaDesignInit(); oa::oaLibDefList::openLibs(); oa::oaNativeNS nns; oa::oaScalarName slib(nns, argv[1]), scell(nns, argv[2]), sview(nns, argv[3]); oa::oaDesign *design = oa::oaDesign::open( slib, scell, sview, 'r' ); oa::oaBlock *block = design->getTopBlock(); oa::oaIter<oaNet> iter(block->getNets()); while (oa::oaNet *net = iter.getNext()) { oa::oaString str; std::cout << (net->getName(nns,str),str) << std::endl; } } 11 Perl: Dump Nets use oa::design; oa::oaLibDefList::openLibs(); $design = oa::oaDesign::open($ARGV[0], $ARGV[1], $ARGV[2], "r"); $block = $design->getTopBlock(); $iter = new oa::oaIter::oaNet($block->getNets()); while ($net = $iter->getNext()) { print($net->getName()."\n"); } 12 Python: Dump Nets import sys import oa.design oa.oaLibDefList.openLibs() design = oa.oaDesign.open(sys.argv[1], sys.argv[2], sys.argv[3], 'r') block = design.getTopBlock() for net in block.getNets(): print net.getName() 13 Ruby: Dump Nets require 'oa' Oa::OaLibDefList.openLibs design = Oa::OaDesign.open(ARGV[0], ARGV[1], ARGV[2], 'r') block = design.getTopBlock block.getNets.each {|net| puts net.getName } 14 Tcl: Dump Nets package require oa oa::oaLibDefList_openLibs set design [oa::oaDesign_open [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] "r"] set block [$design getTopBlock] oa::foreach net [$block getNets] { puts [$net getName] } 15 C#: Dump Nets using System; using OpenAccess_4; namespace DumpNets { class NetDumper { static void Main(string[] args) { oaLibDefList.openLibs(); oaNameSpace.push(new oaNativeNS()); oaDesign design = oaDesign.open(args[0], args[1], args[2], 'r'); oaBlock block = design.getTopBlock(); foreach(oaNet net in block.getNets()) { Console.WriteLine("{0}", net.getName()); } } } } 16 Comparison of oasPython to pyoa • Existing Python wrappers (LSI Python; “pyoa”) http://www.si2.org/openeda.si2.org/projects/python4oa • Performance problems previously seen are now resolved and oasPython is 2~4X faster than pyoa (SWIG 2.0.4) • Slight syntax differences (a fix-it module is provided to allow most pyoa code to be compatible with OAS Python) – Drop “_static” on static methods: oaDesign.static_find => oaDesign.find – Drop “Iter” methods (collections can become an iterator): oaBlock.getInstsIter => oaBlock.getInsts 17 Comparison of oasTcl to oaTcl • Existing Tcl wrappers (Cadence Tcl; “oaTcl”) • Name differences – Slight differences in static method names: DesignOpen oaDesign_open – Differences in OOP structure for method calls: [getTopBlock $design] [$design getTopBlock] • Other: – oaTcl uses “user units” (float); oasTcl uses “DB units” (integer) – the use of user units as a float is currently being enabled in oasTcl – oaTcl lists of floats for oaPoint, oaBox; oasTcl returns the wrapped class which allows method calls: $box1 contains $box2 set point3 [$point1 + $point2] puts [$point toStr] 18 Future usability ideas • Philosophical Question: – How closely should we tie ourselves with C++ API? – How should we differentiate convenience methods from the pure C++ API? Use a separate module? – Note: some convenience functions are already built-in (e.g. string and user unit conversions) • Prototype: quickly get/set oaObject properties (Ruby): shape.props[:foo] = 'bar' shape.props[:number] = 99 shape.props[:foo] shape.props[:number] • Idea: pull lib.def entries into a hash array 19 Future goals • 2011 goals – 8/11 – oaAppDef support for Perl and C# (already in Tcl, Python, Ruby) – 10/11 – Finalize on special oaScript features (UUDBU conversion) – 12/11 – Production release (v1.0) • Future goals – oaObserver support – Region query support – Enable plugins in scripting languages – Add convenience functions, extensions. – Additional languages? 20 Usage to date • Current usage – Hierarchy traverser – Simple schematic/layout GUI interface – Library utilities (e.g. create library, attach to techlib) – Create DM properties on lib, cell, view, and/or cellview from YAML – Design statistics reporting – Interacting with design with embedded OA scripting in EDA tools – OA-based design migration software • Future usage – Real-time web reporting? – Simple open-source design editor? 21 Usage within OpenPDK • Used in Si2 OpenPDK working group to extract symbol information and export to SVG and YAML 22.