OpenAccess and OAScript: The Open EDA Database Standard
If you work in IC design automation, physical design, or EDA tool development, you have almost certainly touched OpenAccess data — quite possibly without knowing it. Cadence Virtuoso, every major place-and-route tool, and dozens of commercial and open-source utilities either read from or write to OpenAccess databases. Understanding the database standard itself, and knowing how to drive it programmatically with OAScript, makes you significantly more effective at building flows, debugging data problems, and writing design automation.
This post covers everything from what OpenAccess actually is — the standard, the history, the licensing reality — through the object model, building from source, the OAScript Tcl shell, practical code examples, and how OpenAccess compares to the alternatives you will encounter in real flows.
What OpenAccess Is
OpenAccess is an open-standard C++ API and database format for integrated circuit design data. It provides a unified programmatic interface to IC design databases covering physical layout, schematics, netlists, and abstracts. The standard is maintained by SI2 (Silicon Integration Initiative), a non-profit semiconductor industry consortium whose membership includes most of the major EDA vendors and semiconductor companies.
The practical effect of the standard: a Cadence Virtuoso layout database, a Synopsys IC Compiler II design, and a standalone OAScript program all speak the same object model. The same API calls — same class names, same methods, same namespace — work across tools. That portability is the entire point.
History
OpenAccess originated inside Cadence Design Systems, where it was developed as the storage backend for Virtuoso. In 2004, Cadence donated the technology and source code to SI2 under an open-access license, making it available to the entire industry. This was a significant moment: Cadence was giving away the database that underpinned its flagship product so that the industry could standardize around a single format and reduce the integration friction between tools.
After donation, SI2 formed the OpenAccess Coalition to govern the standard. Synopsys, Mentor Graphics (now Siemens EDA), Magma Design Automation, and other EDA vendors joined as coalition members. The release that stabilized the public API and remains the reference today is OpenAccess 22 (also referred to as oa22 in filenames and directory structures). The version numbering reflects internal Cadence history, not the year — oa22 predates the SI2 donation.
Development activity on the SI2 OpenAccess codebase has slowed significantly since the mid-2010s. The standard is stable and mature; commercial tools have their own internally optimized implementations of the same API. But the reference source remains publicly available through SI2.
What OpenAccess Provides
OpenAccess is several things at once:
A database format. On disk, an OpenAccess library is a directory tree of binary .oa files — one per cell/cellview combination plus library and technology metadata. The format is documented and the reference implementation can read/write it.
A C++ class library. The primary interface to OpenAccess is a rich C++ API (roughly 300+ classes) covering every concept in IC design: libraries, cells, cellviews, instances, nets, terminals, shapes, layers, vias, design rules, and more. Commercial EDA tools typically embed this C++ library directly.
A Tcl scripting environment (OAScript). The oaScript executable is an interactive Tcl shell with all OpenAccess C++ objects wrapped as Tcl objects. It ships with the OpenAccess source distribution and is the most accessible way to drive OA databases without writing C++.
A technology database system. The technology database (tech.oa) stores layer definitions, purpose definitions, layer-purpose pair rules, via definitions, connectivity rules, and physical design rules — everything a tool needs to interpret the physical meaning of design data.
Who Uses It
Cadence Virtuoso is the most widely deployed OpenAccess consumer. The Virtuoso database is an OA database. When you open a cell in Virtuoso’s layout editor (Virtuoso Layout Suite, VLS), you are looking at an OpenAccess cellview. The SKILL scripting environment in Virtuoso exposes these same objects through SKILL bindings to the underlying OA API. When Virtuoso reads a cds.lib and opens cells, it is opening OA libraries from disk.
Synopsys tools including IC Compiler II and PrimeTime have OA database connectivity. IC Compiler II (ICC2) can work directly with OA databases, sharing data with Virtuoso without intermediate format translation.
Siemens EDA (formerly Mentor Graphics) tools including Calibre can be invoked against OA-native data through connectivity layers, though Calibre’s native input is typically GDSII or OASIS streams.
Ansys (formerly Apache) power analysis and signal integrity tools consume OA data directly.
Open-source tools: OpenROAD (the open-source RTL-to-GDSII flow) uses OpenDB, a separate database standard inspired by but not directly descended from OA. KLayout has partial OA reading capability in its open-source build and more complete OA support in its commercial edition.
The OpenAccess Object Model
Understanding the object model is the prerequisite for everything else. OpenAccess has a strict hierarchy, and every operation is anchored to a position in that hierarchy.
The Database Hierarchy
oaSession (the singleton session object)
└── oaLib (library — a collection of related cells)
└── oaCell (a logical design unit — an AND gate, a memory, a full chip)
└── oaCellView (one view of a cell — layout, schematic, netlist, abstract...)
├── oaBlock (the layout/netlist container within a cellview)
│ ├── oaInst (instance of another cell placed in this design)
│ ├── oaNet (a logical or physical wire)
│ ├── oaTerm (a terminal — the port interface)
│ ├── oaPin (physical pin shape attached to a terminal)
│ └── oaShape (polygon, path, rect, label, etc.)
└── oaTech (technology database, associated with a library)
Libraries
An oaLib represents a library — a directory on disk containing a set of related cells. Libraries come in two flavors:
Design libraries contain actual design content: schematics, layouts, netlists, abstracts. A PDK (Process Design Kit) ships as a collection of design libraries containing the standard cells, IO cells, and IP blocks available in that process.
Technology libraries contain the technology database (tech.oa) with all process-specific information — layers, purposes, design rules, via definitions. In practice, a technology library is typically associated with one or more design libraries through a library reference mechanism.
On disk, a library is a directory with a lib.defs-style registration mechanism. Virtuoso uses cds.lib to map library names to filesystem paths. The OA API uses oaLibDefList to read this mapping.
Cells and Cellviews
An oaCell is a named design unit within a library. It corresponds to a component: an inverter, a flip-flop, an SRAM block, an entire chip. The cell name is the identifier that other designs reference when they instantiate it.
An oaCellView is one representation (view) of a cell. A single cell will typically have multiple views:
| View name (by convention) | Content |
|---|---|
layout |
Physical layout — shapes on layers |
schematic |
Schematic diagram — symbols, wires |
symbol |
Symbol representation for placing in schematics |
netlist |
Structural netlist (SPICE, Verilog, etc.) |
abstract |
Abstract LEF-style view for P&R tools — pins, blockages, no internal detail |
verilog |
RTL or gate-level Verilog |
config |
Configuration view for running simulations |
The view type is separate from the view name. OA tracks both: the name (a string like "layout") and the type (an enum value like oacMaskLayout). Most tools key on the name by convention, but some operations require the correct type.
The actual content of a cellview lives in an oaBlock. For layout, the block contains all the shapes, instances, nets, and terminals. For netlists, it contains instances and connectivity.
Instances and Masters
An oaInst is an instantiation of one cellview inside another. The master is the cell/cellview being referenced; the instance is the placed copy within a containing design.
Instance placement (in layout) is defined by a transformation: a translation (X, Y) and optional rotation/mirroring. OA represents this as an oaTransform, which combines an oaPoint for the origin and an oaOrient enum for orientation (R0, R90, R180, R270, MX, MY, MXR90, MYR90).
Instances can be fixed (fully placed) or unplaced (logical, no physical location). Mixed-signal flows often have unplaced instances at the schematic level that acquire physical placement later in the flow.
Nets, Terms, and Pins
These three objects represent connectivity and deserve careful distinction:
oaNet is a logical wire — a named signal node. In a netlist view, nets connect instances together. In a layout view, nets can also exist to carry connectivity annotations to shapes.
oaTerm (terminal) is a port on a cellview — the interface point through which the design communicates with the outside world. Terminals have a name (VDD, GND, A, B, OUT…) and a direction (input, output, inout, supply, ground, etc.). Terminals exist at the cellview boundary.
oaPin is the physical manifestation of a terminal — a shape (or set of shapes) on a specific layer that physically realizes where the terminal can be connected. A terminal can have multiple pins (e.g., power rails that appear on multiple metal layers). Pins reference both their parent terminal and their parent net.
The relationship: a net has terminals connected to it, and each terminal has one or more pins that define where on the layout the signal is accessible.
Shapes
oaShape is the base class for all geometric objects in a layout. The concrete subclasses are:
| Class | Description |
|---|---|
oaRect |
Rectangle defined by lower-left and upper-right corners |
oaPolygon |
Arbitrary polygon defined by a point array |
oaPath |
Centerline path with a width and optional end styles |
oaPathSeg |
Single segment of a path |
oaEllipse |
Ellipse |
oaArc |
Arc |
oaText |
Text label |
oaAttrDisplay |
Attribute display (used in schematics) |
oaDot |
A dot |
Every shape lives on a specific layer-purpose pair (LPP).
Layers, Purposes, and LPPs
The technology database defines all layers in the process. Layers correspond to physical manufacturing masks: metal layers (M1, M2, …), via layers (VIA1, VIA2, …), diffusion, polysilicon, well layers, etc. Each layer has a name and a numeric layer number.
Purposes add a second dimension to layer classification. A purpose describes the role a shape serves on its layer. Common purposes:
| Purpose name | Meaning |
|---|---|
drawing |
The primary geometry — what gets manufactured |
pin |
Pin shapes defining connectivity access points |
net |
Net name labels |
text |
Non-electrical annotations |
boundary |
Cell boundary definition |
blockage |
Routing blockage |
fill |
Metal fill |
outline |
Physical outline |
A layer-purpose pair (LPP) is the combination of layer + purpose that fully identifies the “layer” a shape lives on. An oaLayerHeader on drawing is the actual metal geometry. An oaLayerHeader on pin is the pin access shape. When you query shapes on a layer, you typically need to specify both layer and purpose.
In the API, layers and purposes are referenced by integer numbers (from the tech database) for performance, not by name. The technology database provides the name-to-number mapping via oaLayer::find() and oaPurpose::find().
Coordinate System and DBU
All coordinates in OpenAccess are integers in database units (DBU). The technology database defines the DBU-to-micron conversion ratio (typically 1000 or 2000 DBU per micron, meaning 1 DBU = 1 nm or 0.5 nm respectively). This is the userunit and DBUPerUU relationship stored in the tech database.
The important implications:
- You never use floating-point coordinates in OA. Everything is integer DBU.
- To place a shape at (0.5 µm, 1.0 µm) with 1000 DBU/µm, you use coordinates (500, 1000).
- Grid snapping is enforced by convention, not by the database, but DRC will catch off-grid shapes.
Coordinates are represented as oaPoint(x, y) where x and y are oaCoord (a typedef for int). Bounding boxes are oaBox(lowerLeftX, lowerLeftY, upperRightX, upperRightY).
Physical vs. Logical Views
OpenAccess cleanly separates physical views (layout) from logical views (schematic, netlist). The distinction matters for scripting:
Physical views (oacMaskLayout type, typically named layout) contain shapes, instances with physical placement, routing, and pins as geometric objects. The coordinate system and layers are meaningful.
Logical views (oacSchematic, oacNetlist, oacVerilog) contain instances, nets, and terminals but no physical geometry. Instances may have symbolic positions for display but no manufacturing-meaningful placement.
Abstract views (oacAbstract) are an interesting middle ground: they contain the bounding box and pin shapes of a cell (enough for a P&R tool to route to), but not the internal layout detail. LEF files are essentially abstract views in a different format.
Getting Access to OpenAccess
SI2 Membership and Access
The OpenAccess source code is available through SI2 (Silicon Integration Initiative) at si2.org. Access is tiered:
SI2 member companies get full access to the source repository, development mailing lists, and technical support. SI2 membership requires an annual fee based on company revenue tier. The membership roster includes the major EDA companies, semiconductor manufacturers, foundries, and many mid-sized design houses. For a company doing serious IC design work, SI2 membership is standard.
Non-members can access a publicly released snapshot of the source via the SI2 website, subject to signing the OpenAccess License Agreement (OALA). The OALA is a royalty-free license that allows use in commercial and academic work but includes attribution requirements and restricts redistribution of the source in modified form. It is considerably more permissive than commercial EDA licenses.
Academic access is available through a separate academic program with reduced fees and the same OALA terms. Many university EDA research programs use OpenAccess as their database substrate.
The honest state of things in 2026: the publicly available source is several years behind the internal versions used in commercial tools. Cadence’s internal OA implementation in Virtuoso, and Synopsys’s in ICC2, are both more recent than what SI2 distributes. The public source is sufficient for learning, tool development, and building standalone utilities, but you will not be programming the exact same binary that Cadence ships.
License Agreement Reality
The OALA is not open source in the OSI sense. Key points:
- Free to use in any product, commercial or academic.
- Source redistribution requires attribution and SI2 notification.
- You cannot sublicense the source under a different license.
- Binary redistribution (shipping an OA-based tool) is allowed.
This licensing model is why OpenAccess is not packaged in Linux distributions and why you will not find it in package managers. Every consumer has to build from source or link against a pre-built binary from their EDA vendor.
Build Requirements
OpenAccess builds on Linux. In practice, Linux is the only supported platform — specifically RHEL/CentOS-family and derivatives. MacOS and Windows builds are not supported by SI2 and are not a practical option for production use.
The build requires specific tool versions that track the toolchain assumptions baked into the OA source. As of the oa22 reference release:
- GCC: the supported version is older than current GCC. The codebase was developed and tested against GCC 4.x–6.x. Building with GCC 9+ requires pragmas to suppress deprecated-copy warnings and may require patching. If your distribution ships GCC 11+, you will need either a compatibility GCC installation or a patch set.
- Tcl/Tk: version 8.4 or 8.5. OAScript was written against the Tcl 8.x C API. Tcl 8.6 works but has subtle differences; Tcl 9.x is not supported.
- OpenSSL: required for certificate-based licensing features in some builds. Version 1.x; OpenSSL 3.x has API changes that require patching.
- Doxygen: needed only for building the HTML API documentation from source.
- GNU Make: the build system is pure Makefile, no CMake or autoconf.
- Python 2.x: some build scripts use Python 2 syntax. Python 3-only environments need to adjust shebang lines.
The dependency on older toolchain versions is the single biggest practical challenge when building OA on a modern Linux system (RHEL 9, Ubuntu 22.04+). The recommended approach for a modern host is to use a Docker container or Podman container with RHEL 8 / CentOS Stream 8 and the appropriate GCC version from devtoolset.
Building OpenAccess from Source
Source Layout
After unpacking the OA source tarball, the top-level directory structure is:
oa/
├── src/ # C++ source for all OA libraries
│ ├── oa/ # Core database implementation
│ ├── oaBase/ # Base types and utilities
│ ├── oaDM/ # Design management (library/cell/cellview CRUD)
│ ├── oaCommon/ # Shared infrastructure
│ ├── oaTech/ # Technology database
│ └── oaScript/ # OAScript Tcl interpreter
├── include/ # Public C++ headers
│ └── oa/ # All oa*.h headers live here
├── lib/ # Output directory for compiled shared libraries
├── bin/ # Output directory for executables including oaScript
├── data/ # Tech database templates, built-in layer definitions
├── doc/ # Documentation source (Doxygen markup)
└── Makefile # Top-level build entry point
Environment Variables
Before building, set the following environment variables:
|
|
The OA_COMPILER variable is critical. The build system uses it as a directory component for all output — compiled objects go into subdirectories keyed by this string, which allows multiple compiler/OS combinations to coexist in one source tree.
Build Steps
|
|
A full build takes 15-30 minutes on a modern workstation. The output libraries are shared objects (libOA*.so) in lib/${OA_COMPILER}/${OA_TOOLKIT}/ and the oaScript binary in bin/${OA_COMPILER}/${OA_TOOLKIT}/.
Common Build Errors and Fixes
error: implicitly-declared ... is deprecated (GCC 9+)
The OA codebase has classes where copy constructors/assignment operators are implicitly deprecated under newer C++ standards. Fix by adding to the relevant Makefile fragment:
|
|
openssl/md5.h: No such file or directory
OpenSSL 3.x moved the legacy MD5 header. Install openssl-devel (or libssl-dev) for your distribution, or patch the include path:
|
|
Or, in the source, find the #include <openssl/md5.h> references and add a compatibility shim.
Tcl header not found
|
|
undefined reference to link errors
The link order in the OA Makefiles assumes the GNU linker’s behavior for shared library resolution. If you get undefined reference errors at link time, ensure the OA_COMPILER string exactly matches a known configuration and that the .so files from a previous partial build are not stale. make clean && make from scratch resolves most linker issues.
Post-Build Verification
After a successful build, verify the OAScript binary exists and starts:
|
|
The % prompt indicates a live OAScript session.
OAScript: The Tcl Shell for OpenAccess
What OAScript Is
OAScript is an interactive Tcl interpreter that has the entire OpenAccess C++ API exposed as Tcl commands. Every OA C++ class becomes a Tcl command prefix; every method becomes a subcommand. The C++ objects are wrapped as opaque Tcl handles — you manipulate them by passing the handles to the appropriate commands.
The wrapping is mechanical but complete: if the C++ API has oaLib::open(libName, mode), OAScript has oa::Lib open libName mode. If the C++ class has a getCell() method returning an iterator, the Tcl equivalent returns a list.
The oa Namespace
All OAScript commands live in the oa:: namespace. You reference them as oa::ClassName for constructors/static methods and pass object handles to commands for instance methods. The namespace approach avoids collision with standard Tcl commands and with any other Tcl packages you might load.
|
|
The handle returned by oa::Lib open is a Tcl value that represents the C++ oaLib* pointer. You cannot inspect it directly — it is opaque. You use it only as an argument to subsequent oa:: commands.
Starting OAScript
Standalone interactive session:
|
|
This drops you into the % prompt. Standard Tcl constructs work normally: variables, lists, dicts, procs, if, for, foreach, while, puts, file I/O — all of standard Tcl is available alongside the oa:: commands.
Running a script file non-interactively:
|
|
Sourcing a script from within an interactive session:
|
|
In Cadence Virtuoso’s CIW (Command Interpreter Window):
Virtuoso embeds OAScript semantics through its SKILL environment. You cannot run raw OAScript commands in the CIW — you use SKILL functions that internally call the OA C++ API. However, you can load OAScript-style Tcl inside Virtuoso using the Virtuoso Tcl integration:
|
|
For batch automation outside Virtuoso, the standalone oaScript binary is the right tool. For automation inside Virtuoso, SKILL (or the hiXxx API) is more natural, though the underlying objects are the same OA objects.
Loading OA Plugin Libraries
OAScript needs to know about any plugin libraries (translators, PDK-specific functionality) you want to use. The oaLibDefList mechanism handles library discovery:
|
|
For standalone work, you create a minimal lib.defs file:
DEFINE myDesignLib /path/to/myDesignLib
DEFINE myTechLib /path/to/myTechLib
OAScript API Reference and Usage Patterns
Session and Library Management
The session is a singleton — you do not create it; it exists as soon as oaScript starts. Library operations are the entry point to everything:
|
|
Iterating Over Cells and Cellviews
|
|
The iterators in OAScript are returned as Tcl lists you can iterate with foreach. In the C++ API, these are oaIter<> objects; in Tcl, they are already materialized as lists.
Opening a Cellview
|
|
Note: oa::DesignOpen is the convenience entry point; it takes library/cell/view strings directly. It is equivalent to the longer navigate-and-open sequence. Both are common in practice.
Accessing Instances
|
|
Iterating Over Shapes in a Layout
|
|
Creating Layout Programmatically
This example creates a new cellview with a rectangle, a path, and an instance:
|
|
Working with Nets and Connectivity
|
|
Technology Database Access
|
|
Saving and Closing
|
|
Common Scripting Patterns for Design Automation
Batch Script Template
A well-structured OAScript batch script follows this pattern:
|
|
Running as Part of a Makefile Flow
|
|
Hierarchical Traversal
A common pattern is hierarchical traversal — processing not just a top-level design but all cells it instantiates:
|
|
Integration with EDA Flows
Inside Cadence Virtuoso
Within Virtuoso, you do not run oaScript directly — you use the SKILL programming environment. SKILL is a Lisp dialect that exposes the same OA object model through a different syntax and naming convention. The underlying objects are the same OA C++ objects.
However, Virtuoso does expose a Tcl bridge. You can call Tcl/OAScript code from within Virtuoso using the built-in Tcl interpreter:
|
|
The typical integration pattern for teams using both SKILL and standalone OAScript:
- Interactive, session-based design editing: SKILL or the Virtuoso GUI
- Batch processing, reporting, cross-tool data exchange: standalone oaScript scripts called from a Makefile or LSF/Slurm job
Running Standalone Batch Jobs
For batch automation, the full invocation pattern in a cluster environment:
|
|
Submit to a cluster:
|
|
Scripting Cadence OCEAN with OA Backends
OCEAN (Open Command Environment for Analysis) is Cadence’s simulation scripting language, sitting on top of SKILL/OA. OA data flows through OCEAN scripts transparently. If you are writing OCEAN scripts and need to access the OA database directly, you can drop into the OA layer:
|
|
The oa_ prefix functions in SKILL map directly to OA C++ calls.
Comparison to Alternatives
SKILL vs. OAScript
SKILL (Simulation Knowledge Interpretation Language) is Cadence’s proprietary Lisp-based scripting language embedded in Virtuoso. It is not the same as OAScript, though both can manipulate OA data.
| Aspect | SKILL | OAScript |
|---|---|---|
| Language base | Lisp (with unique Cadence extensions) | Tcl (standard) |
| Availability | Cadence Virtuoso only | Standalone, any OA-capable tool |
| Object names | dbOpenCellViewByType, geCreateRect… |
oa::DesignOpen, oa::Rect create… |
| Documentation | Cadence SKILL Language Reference (CDNS subscription) | SI2 OA API docs (SI2 member access) |
| Community | Large — decades of SKILL scripts in industry | Smaller but exists |
| Portability | None (Cadence only) | Any OA implementation |
| Interactive | Yes (CIW in Virtuoso) | Yes (oaScript prompt) |
| Maturity | Very mature | Mature (development slowed) |
For work that only ever runs inside Virtuoso, SKILL is more natural — the function names map more directly to Virtuoso UI concepts, the documentation is more complete, and there are more code examples. For cross-tool automation, batch processing outside Virtuoso, or writing tools that need to run on multiple EDA platforms, OAScript is the portable choice.
A common real-world pattern: use SKILL for interactive Virtuoso automation and use OAScript for batch flows that run on farm machines without a Virtuoso license.
Python and OA
There is no official Python binding for OpenAccess in the SI2 distribution. Unofficial Python wrappers exist in some academic and internal tool distributions, typically implemented as SWIG-generated wrappers around the C++ API, but these are not part of any standard release.
KLayout (the widely used open-source/commercial layout viewer and editor) has a Python API (klayout.db) that can read and write GDSII, OASIS, DXF, and has partial OA reading capability. KLayout’s OA support is more complete in the commercial edition and reads OA data by embedding the OA C++ library. You can drive KLayout’s OA-aware operations from Python through the KLayout Python API, but you are going through KLayout’s abstraction, not talking to OA directly.
For Python-native IC design database access, the OpenROAD project’s OpenDB (now maintained as part of OpenROAD and accessible via its Python bindings) is the most actively developed open option, though OpenDB targets the P&R domain rather than the full OA scope.
OA vs. GDSII/OASIS
GDSII (Graphic Design System II, now officially called DFII) and OASIS (Open Artwork System Interchange Standard) are streaming formats — they represent a flat or hierarchical snapshot of physical layout at tape-out time. They are not databases you work in; they are interchange formats you export from and import to.
| OpenAccess | GDSII / OASIS | |
|---|---|---|
| Primary use | Working database during design | Tape-out stream, tool exchange |
| Format | Directory of binary .oa files |
Single binary stream file |
| Incremental edit | Yes | No (stream in/stream out) |
| Schematic/netlist | Yes | No (layout only) |
| Technology data | Yes (in tech.oa) | Partial (layer map only) |
| Hierarchy | First-class (instances reference cells) | Cell references in the stream |
| Design rules | Yes | No |
| Version control | Via library management | Whole-file versioning |
| Open standard | Yes (SI2) | Yes (Semiconductor Equipment and Materials International) |
In practice, GDSII or OASIS is what you hand to a foundry or a mask shop. OA is what you work in during design. A final step in the tape-out flow converts OA to GDS/OASIS for delivery.
OA vs. LEF/DEF
LEF (Library Exchange Format) and DEF (Design Exchange Format) are ASCII text formats used by place-and-route tools.
- LEF encodes the technology (layers, vias, grid rules) and cell abstracts (bounding boxes, pin shapes, obstruction geometry). It is approximately equivalent to the technology database + abstract views in OA.
- DEF encodes a placed-and-routed design: the netlist, the placed component locations, the routing geometry. It is approximately equivalent to a placed OA layout cellview.
The P&R flow from a tool like Synopsys DC + Synopsys ICC2 or Cadence Innovus traditionally used LEF/DEF for tool interoperability. Modern flows (especially ICC2 working with Virtuoso) increasingly use OA natively, with LEF/DEF available as an interchange format for tools that do not support OA directly.
OA vs. OpenDB
OpenDB is the database used by OpenROAD, the open-source RTL-to-GDSII flow. It was originally developed at Silicon Intelligence and is now maintained by the OpenROAD project. OpenDB has Python bindings and is actively developed.
| OpenAccess | OpenDB | |
|---|---|---|
| Governance | SI2 (industry consortium) | OpenROAD project (UCB ORFS) |
| Language bindings | C++, Tcl (OAScript) | C++, Python, Tcl |
| Scope | Full IC design (layout, schematic, netlist) | P&R focused (netlist, placement, routing) |
| Schematic support | Yes | No |
| Technology DB | Full OA tech | Simplified (from LEF) |
| Activity level (2026) | Maintenance mode | Actively developed |
| License | OALA (SI2) | BSD-3 |
| Availability | SI2 member portal | GitHub (The-OpenROAD-Project/OpenROAD) |
If you are working in open-source EDA flows with OpenROAD, OpenDB + Python is the practical choice. If you are working in a commercial EDA environment with Virtuoso or ICC2, OpenAccess is the standard you are working against.
Common Pitfalls and Gotchas
Database Locking
OpenAccess uses file-system-level locking for write access. When you open a cellview with oaViewOpenMode_readWrite, OA creates a lock file in the library directory. If your script crashes or exits uncleanly, the lock file may be left behind, preventing any other tool from opening that cellview for writing.
Lock files are named <cellName>.<viewName>.oa.lck and live alongside the .oa data files. They contain the hostname and PID of the locking process. If the lock is genuinely stale (the process is dead), you can delete the .lck file manually. Never delete a lock file for a process that might still be running — you will corrupt the database.
In scripts, always close cellviews in a catch/cleanup block:
|
|
Tcl’s finally clause is available in Tcl 8.6+. For older Tcl, use nested catch blocks.
The Transaction Model
OpenAccess has a transaction model for write operations, but it is not exposed through OAScript in the way database transactions are. In the C++ API, you call oaDesign::beginAccess() and oaDesign::endAccess() around write operations. In OAScript, this is implicit — opening a design in read-write mode begins a transaction, and saving commits it.
The implication: partial writes are possible if your script crashes between shape creation and $cv save. There is no rollback mechanism in OAScript. Design the script so that all modifications are in-memory until a single $cv save at the end.
Reference Counting and Memory
In the C++ API, many OA objects are reference counted and can be explicitly destroyed. In OAScript, object lifetimes are managed by the Tcl interpreter’s garbage collection, but this does not map cleanly to OA’s own reference counting. In long-running scripts that process thousands of cellviews, you can accumulate memory from OA objects that Tcl has not yet GC’d.
Mitigation: explicitly close designs when you are done with them ($cv close or $cv purge). The purge variant is stronger — it removes the design from OA’s internal cache, freeing more memory. For batch scripts processing hundreds of designs in a loop, close and purge after each iteration.
|
|
Platform Compatibility
OpenAccess .oa files include a version marker. A database written by a newer OA version may not be readable by an older OA version. In practice:
- Files written by Virtuoso (using Cadence’s internal OA implementation) are generally readable by the SI2 reference implementation at the same major API revision.
- Files written with Virtuoso 22.x features may use OA schema extensions not in the public oa22 source.
- Mixing OA versions in a multi-tool flow (e.g., Virtuoso 22.x writes, standalone oa22.04 reads) requires testing. Minor version differences are usually fine; major OA API version differences can cause read errors.
The version of the .oa files can be inspected with the oaDesign::getRevision() call or by looking at the binary header of the file (not recommended directly).
OAScript vs. the OA API Inside a Commercial Tool
When you write OAScript code and run it with the standalone oaScript binary, you are using the SI2 reference implementation of OA. When Cadence Virtuoso or Synopsys ICC2 opens the same OA database, it is using that tool’s internal OA implementation (which is based on the same standard but may have internal optimizations, extensions, and different performance characteristics).
The observable differences:
- Performance: Commercial tool implementations are typically faster for large databases.
- Extensions: Cadence has OA schema extensions used by Virtuoso for schematic-specific metadata that are not in the public OA specification. Reading these extended attributes from standalone oaScript returns default/empty values.
- Licensing metadata: Some tools embed license-check objects in OA databases (for IP protection). The reference implementation reads these as generic properties.
- Error handling: Error messages and error codes differ between the reference implementation and commercial implementations.
The API — class names, method signatures, behavior for standard operations — is the same. If your oaScript code correctly opens a library, reads instances, and prints net names, it will produce the same results as equivalent C++ code in a commercial tool against the same database.
Documentation Gaps
Be aware that documentation availability varies significantly by what you are trying to do:
Well-documented (SI2 public docs):
- The C++ class reference (accessible after SI2 registration)
- OAScript command syntax (mirrors the C++ API 1:1)
- The OA schema: what objects exist and what they contain
Sparsely documented or tool-specific:
- Technology database constraint APIs (spacing rules, antenna rules) — the public docs cover the framework but not every constraint type
- Cadence Virtuoso-specific OA extensions (pcell parameterized cells, the cellview config view, connectivity rules used by Spectre)
- The exact format of
.oabinary files on disk (not publicly documented; OA is API-access only) - OA event/callback infrastructure (used by tools for incremental update)
Not in public docs — requires working code:
- PCell (parameterized cell) evaluation. PCells are OA cellviews with embedded code that generates geometry on-the-fly. The public OA API has a PCell framework, but actual PCell compilation is handled by Cadence’s Virtuoso with SKILL callbacks. Understanding how PCells work requires Virtuoso documentation (Cadence support portal).
- The DM (Design Management) plugin system used to integrate OA with version control systems like DesignSync.
A Note on Current State (2026)
The SI2 OpenAccess reference implementation has been in maintenance mode for several years. Active development has shifted to commercial tool vendors’ internal forks and to newer open-source alternatives like OpenDB.
For learning OA and writing portable design automation tools, the reference implementation and OAScript are still the right starting point — the standard is stable, the object model is well understood, and any knowledge you build transfers directly to working with Virtuoso’s OA layer through SKILL or to commercial OA C++ plugin development.
For greenfield open-source EDA tool development in 2026, evaluate OpenROAD/OpenDB alongside the OA reference — OpenDB has active development, good Python bindings, and permissive licensing. If your flow is entirely within the Cadence ecosystem, invest in SKILL proficiency alongside OAScript; both operate on the same underlying objects.
The EDA database landscape is one of the most balkanized areas in engineering tooling. OpenAccess remains the most successful attempt at a true open standard for IC design data — imperfect, showing its age, but widely deployed and worth understanding deeply.
Quick Reference
Key Environment Variables
|
|
Common OAScript Commands
|
|
Open Mode Constants
|
|
Comments