OpenAccess supports parameterized cells (Pcells). Pcells are oaDesigns, which have content that is dynamically created based on a set of parameters. An application can provide different versions of Pcells by implementing a specialized Pcell evaluator; in this way, OpenAccess has the ability to support multiple Pcell evaluators at runtime. These evaluators can be statically bound to an application, but it is recommended that they be implemented as a plug-in. Some Pcell evaluators, such as the OpenAccess C++ Pcell evaluator, call functions written by a user in C++ in order to generate a database for a particular Pcell instance. Other possibilities are Pcell evaluators that can invoke engines such as Tcl or Skill to execute scripts stored in Pcell masters in order to generate the appropriate OpenAccess structures.
This document explains how to write a PCell evaluator plug-in. Additional information on writing a plug-in is available in the companion document How to Write a Plug-In.
OpenAccess uses superMasters and subMasters to define and manage Pcells. A superMaster is an oaDesign that contains the information necessary to generate different variations of itself based on a set of parameters. A superMaster is created through the oaDesign::defineSuperMaster() API, where the Pcell evaluator and the set of parameters with default values are specified. An application can create an instance by specifying a superMaster as the master and additionally provide a set of parameters with values usually different from the superMaster defaults.
OpenAccess creates a subMaster as the master for this instance by using the Pcell evaluator specified in the superMaster and by using the parameters specified in the instances. A Pcell evaluator is typically implemented to create the subMasters on the fly in virtual memory. In this case, the application can access the subMaster as a regular oaDesign, except that it cannot be saved to disk persistently.
Alternatively, an application can save subMasters to a file using the PcellFile::append function. The subMasters can be read later by a Pcell evaluator.
You can create a Pcell evaluator plug-in by creating a shared library that can be loaded by OpenAccess at runtime. The shared library must do the following:
After the shared library is created, you must write a plug-in registration file to register your plug-in.
OpenAccess provides the templated class oaCommon::Factory<T> for defining a factory object for a plug-in. The factory object is used to create instances of a plug-in. Each plug-in has a classID, which is put into a factory table. When OpenAccess needs to create an instance of a plug-in, it uses the classID to find the factory for the plug-in. For more information about creating a plug-in factory, see the Understanding the Plug-in Factory section of the companion document on writing a plug-in.
You must also implement the getClassObject entry point function. When called, this function returns a pointer to the plug-in factory. For more information about implementing the getClassObject entry point function, see the Implementing the Entry Point Function section of the companion document on writing a plug-in.
The plug-in registration file registers the plug-in shared library. When the plug-in shared library is installed, the registration file can be installed in $(OA_HOME)/data/plugins. Alternatively, the OA_PLUGIN_PATH environment variable can be used to reference a .plg file outside of $(OA_HOME)/data/plugins. Refer to Writing the Plug-In Registration File in How to Write a Plug-In for more information.
To create a Pcell evaluator plug-in, you must define a new class inherited from the IPcell class. This class implements the interfaces necessary to build and maintain Pcells in an OpenAccess database. The new class must implement all virtual functions of the IPcell class. Refer to the API documentation for IPcell for a detailed description about these virtual functions. OpenAccess uses the oaPcellLink class to form a runtime link to the application provided Pcell evaluator. There can only be one link per Pcell evaluator. In a statically linked Pcell evaluator, an application creates an instance of the evaluator class object and calls oaPcellLink::create() with the instance as the argument. An oaPcellLink is automatically created when a Pcell evaluator is requested by name using oaPcellLink::find() or oaPcellLink::getPcellDef(). The standard OpenAccess plug-in loading and class creation mechanism is used by oaPcellLink to get an instance of the Pcell evaluator class. A description of some of the IPcell virtual functions provides insight into how they interact:
A plug-in is a shared library that is installed in the OpenAccess installation hierarchy in the data/plugins directory, or in another location specified by the OA_PLUGIN_PATH environment variable. Applications load the plug-in at runtime to select a customized implementation. The following procedure describes the steps for creating an example plug-in. For additional guidance on writing a Pcell evaluator plug-in, see the code example in the $(OA_HOME)/examples/oa/PCells/opnPcell directory.
oaCommon::Factory<myPcell> myFactory; oaCommon::Factory<myPcell> myPcell::myFactory("myPcell");
extern "C" long getClassObject(const char *classID, const Guid &interfaceID, void **ptr);
long getClassObject(const char *classID, const Guid &interfaceID, void **ptr) { return FactoryBase::getClassObject(classId, interfaceID, ptr); }
class myPcell : public PlugInBase<IPcell> { public: virtual oaPcellDef *getPcellDef(); virtual void getName(oaString &name) {name = "myPcell";} virtual void onBind(oaDesign *design, oaPcellDef *pcellDef) {} virtual void onUnbind(oaDesign *design, oaPcellDef *pcellDef); virtual void onEval(oaDesign *design, oaPcellDef *pcellDef); virtual void onRead(oaDesign *design, oaMapFileWindow &mapWindow, oaUInt4 &loc, oaPcellDef *def) {} virtual void onWrite(oaDesign *design, oaMapFileWindow &mapWindow, oaUInt4 &loc, oaPcellDef *def) {} virtual oaUInt4 calcDiskSize(oaPcellDef *pcellDef) const; private: static Factory<myPcell> factory; };
virtual bool validate()
<?xml version="1.0" encoding="utf-8" ?> <plugIn lib="myAppPcell"/>Note: The registration file can be installed in $(OA_HOME)/data/plugins when the plug-in shared library is installed. Alternatively, the OA_PLUGIN_PATH environment variable can be used to reference a .plg file outside of $(OA_HOME)/data/plugins. Refer to Writing the Plug-In Registration File in How to Write a Plug-In for more information.
Once the evaluator plug-in is done, an application must be written to create the corresponding Pcell superMasters. You can refer to the PCells.cpp code in $(OA_HOME)/examples/oa/PCells for an example of how you might write an application to create Pcells. The following steps include portions of the PCells.cpp code:
oaPcellDef *def = oaPcellLink::getPcellDef("myPcell");
oaDesignInit(); oaLibDefList::openLibs();
oaParam p1; p1.setName("width"); p1.setDoubleVal(3.0); oaParam p2; p2.setName("length"); p2.setDoubleVal(1.0); oaParamArray paramArray(2); paramArray.append(p1); paramArray.append(p2);
oaScalarName viewName(ns, "layout"); oaScalarName sCellName(ns, "pcell_master"); oaViewType *viewType = oaViewType::get(oacMaskLayout); oaDesign *superMaster = oaDesign::open(libName, sCellName, viewName, viewType, 'w'); superMaster->defineSuperMaster(def, paramArray);
After these steps are completed, when the application needs to create an instance of a Pcell, it simply uses the following call:
Scalarinst = oaScalarInst::create(ptrParentBlock, ptrSuperMaster, xform, paramarray);
Where ptrSuperMaster is a pointer to the oaDesign, which is the superMaster for the Pcell, and the paramArray is the array of the non-default parameters for the instance. An application that is only going to traverse the hierarchy only needs to call getMaster() on the instance, which returns the oaDesign that is the subMaster for that instance. The application can traverse the data on that oaDesign without taking into consideration that it is a Pcell that was generated on the fly.
An application can store multiple Pcell subMasters to a cache file using the PcellFile interface. An application first uses the PcellFile constructor to get a handle to a cache file. The application must call PcellFile::open before appending subMasters to the cache file. The append function returns an offset that indicates the location in the file for that particular subMaster. PcellFile::close() should be called to release the resources associated with the cache file before calling the destructor on the handle.
An application that writes Pcell subMasters to a file is responsible for:
A different application can read a particular cached subMaster from a file. In order to do this, the application needs:
Copyright © 2001-2010 Cadence Design Systems, Inc.
All rights reserved.