an introduction to openaccess scripting...an introduction to openaccess scripting james d. masters...
TRANSCRIPT
111
An Introduction to OpenAccess Scripting
James D. MastersIntel Corp
Design Automation ConferenceJune 6, 2011
222
• 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)
What is it?
333
OA API
Tcl API
Type Mapping
Ruby API
Type Mapping
Perl API
Type Mapping
Python API
Type MappingCommon Wrapper Architecture
Interface
Language-Specific Bindings
C++ Programming Interface
Common SWIG Framework
How does it work?
C# API
Type Mapping
• Common interface through SWIG ensures cross-languageconsistency and reuse
• All languages interface OA through the official OA API
444
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/array
oaTransform/array
OaTransform/Array
oaTransform/list
oaTransform
555
Input string / scalarName values
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");
• All oaScript languages allow a native string to be used in place of an oaScalarName
666
Mapping to OA API documentation
• Similar syntax to the C++ APIStatic Public MethodsoaLib * 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|stringstring|oaLibMode string list|"NULL"
C# OpenAccess_4.oaLib.create(oaScalarName|string, string, oaLibMode, string, oaDMAttrArray)
777
Mapping to OA API documentation
• Sample documentation map to target language
Public MethodsoaBoolean 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);
888
Enumerated wrappers
• Enumerated wrappers (e.g. oaLibMode) are mapped differently in each language
Perl Input: IntegerOutput: Integer
Python Input: Wrapped object, integer, or stringOutput: Wrapped object (can cast to integer value with “__int__”)
Ruby Input: Wrapped object, integer, or stringOutput: Wrapped object (can cast to integer value with “to_i” or string with “to_s”)
Tcl Input: Wrapped object or integerOutput: Wrapped object (can cast to integer value with “$enumWrappertypeEnum”)
C# Input: Native C# enumOutput: Native C# enum
Note: all languages have the enum constants available (e.g. oacReadLibAccess)
999
Collections / Iterators
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()) {...
}
• Map collections/iterators natively in target language; allow native loops when possible
101010
• 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 sectionOa::OaNameSpace.pop
Unique behaviors
111111
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;
}
}
121212
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");}
131313
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()
141414
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
}
151515
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]
}
161616
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());
}}
}}
171717
• 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
Comparison of oasPython to pyoa
181818
• 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]
Comparison of oasTcl to oaTcl
191919
• 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] = 99shape.props[:foo]shape.props[:number]
• Idea: pull lib.def entries into a hash array
Future usability ideas
202020
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?
212121
• 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?
Usage to date
222222
• Used in Si2 OpenPDK working group to extract symbol information and export to SVG and YAML
Usage within OpenPDK