re-add OpenAccessDriver.cpp Oops, and at last .cds file are generated the way we want them to ...

This commit is contained in:
Jean-Manuel Caba 2010-07-30 15:01:57 +00:00
parent 2b78ecef1a
commit 0b9a17f85d
5 changed files with 922 additions and 84 deletions

View File

@ -1,5 +1,5 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-07-26 16:09:36" - OpenAccessCommon.h
// Time-stamp: "2010-07-30 16:48:54" - OpenAccessCommon.h
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
@ -28,14 +28,13 @@ using namespace oa;
#define assert(cond) if (! (cond) ) throw Error("assertion failed : " + string( #cond ) )
//#define assert(cond)
namespace {
namespace {
/**
giving a oaDesign pointer that should be not NULL
return the oaString representing its name
*/
inline oaString getDesignName(oaDesign* design) {
cerr << "getDesignName" << endl;
assert(design);
oaNativeNS ns;
oaString libName, cellName, viewName;
@ -52,7 +51,6 @@ namespace {
@todo remove when not needed anymore
*/
inline void printBlockTerms(oaBlock* block) {
cerr << "printBlockTerms" << endl;
assert(block);
oaNativeNS ns;
oaDesign* design = block->getDesign();
@ -71,7 +69,6 @@ namespace {
@todo verify
*/
inline oaMaterial getOAMaterial(const BasicLayer::Material& material) {
cerr << "getOAMaterial" << endl;
switch ( material.getCode() ) {
case BasicLayer::Material::nWell: return oacNWellMaterial;
case BasicLayer::Material::pWell: return oacPWellMaterial;
@ -81,7 +78,7 @@ namespace {
case BasicLayer::Material::poly: return oacPolyMaterial;
case BasicLayer::Material::cut: return oacCutMaterial;
case BasicLayer::Material::metal: return oacMetalMaterial;
case BasicLayer::Material::blockage:
case BasicLayer::Material::blockage:
//there is no blockage type but a specific oaLayerBlockage class
return oacOtherMaterial;
case BasicLayer::Material::other: return oacOtherMaterial;
@ -90,12 +87,36 @@ namespace {
}
}
/**
@todo complete,verify ...
*/
inline BasicLayer::Material::Code oaMaterialToBasicLayerType(const oaMaterial& material) {
switch(material) {
case oacNWellMaterial:
return BasicLayer::Material::nWell;
case oacPWellMaterial:
return BasicLayer::Material::pWell;
case oacNImplantMaterial:
return BasicLayer::Material::nImplant;
case oacPImplantMaterial:
return BasicLayer::Material::pImplant;
case oacPolyMaterial:
return BasicLayer::Material::poly;
case oacCutMaterial:
return BasicLayer::Material::cut;
case oacMetalMaterial:
case oacContactlessMetalMaterial:
return BasicLayer::Material::metal;
default:
return BasicLayer::Material::other;
}
}
/**
Convertion helper for Net convertion ...
@todo verify
*/
inline oaTermType getOATermType(const Net::Direction& direction) {
cerr << "getOATermType" << endl;
switch (direction) {
case Net::Direction::IN:
return oacInputTermType;
@ -117,7 +138,6 @@ namespace {
@todo verify
*/
inline oaSigType getOASigType(const Net::Type& type) {
cerr << "getOASigType" << endl;
switch (type.getCode()) {
case Net::Type::LOGICAL:
return oacSignalSigType;
@ -136,9 +156,8 @@ namespace {
/**
Convertion helper ...
*/
*/
inline oaOrient getOAOrientFromOrientation(const Transformation::Orientation& orientation) {
cerr << "getOAOrientFromOrientation" << endl;
switch (orientation) {
case Transformation::Orientation::ID:
return oacR0;
@ -163,9 +182,8 @@ namespace {
/**
Convertion helper ...
*/
*/
inline void getOATransformFromTransformation(oaTransform& transform, const Transformation& transformation) {
cerr << "getOATransformFromTransformation" << endl;
transform.set(transformation.getTx(),
transformation.getTy(),
getOAOrientFromOrientation(transformation.getOrientation()));
@ -173,18 +191,17 @@ namespace {
/**
Convertion helper ...
*/
*/
inline void getOABoxForBox(oaBox& box, const Box& hbox) {
cerr << "getOABoxForBox" << endl;
box.set(hbox.getXMin(), hbox.getYMin(), hbox.getXMax(), hbox.getYMax());
}
/**
Create InstTerm representing connection of nets ...
Create InstTerm representing connection of nets between instance
always return a non NULL value
*/
inline oaInstTerm* getInstTerm(oaInst* inst, Plug* plug,oaNet* net) {
cerr << "getInstTerm" << endl;
assert(inst);
assert(plug);
oaNativeNS ns;
@ -225,7 +242,6 @@ namespace {
print the oaLayera in a oaTech ...
*/
inline void printOALayers(oaTech* theOATech){
cerr << "printOALayers" << endl;
assert(theOATech);
oaIter<oaLayer> lIter(theOATech->getLayers());
while(oaLayer* l = lIter.getNext()){
@ -235,34 +251,9 @@ namespace {
}
}
/**
@todo complete,verify ...
*/
inline BasicLayer::Material::Code oaMaterialToBasicLayerType(const oaMaterial& material) {
switch(material) {
case oacNWellMaterial:
return BasicLayer::Material::nWell;
case oacPWellMaterial:
return BasicLayer::Material::pWell;
case oacNImplantMaterial:
return BasicLayer::Material::nImplant;
case oacPImplantMaterial:
return BasicLayer::Material::pImplant;
case oacPolyMaterial:
return BasicLayer::Material::poly;
case oacCutMaterial:
return BasicLayer::Material::cut;
case oacMetalMaterial:
case oacContactlessMetalMaterial:
return BasicLayer::Material::metal;
default:
return BasicLayer::Material::other;
}
}
/**
generate info from library name
*/
*/
inline pair<oaScalarName,string> libInfos(const string& path,
const string& libName){
oaNativeNS ns;
@ -274,7 +265,7 @@ namespace {
/**
open oaLib with the info gathered by libPath function
*/
*/
inline oaLib* openOALib(const pair<oaScalarName,string>& infos){
oaLib *lib = oaLib::find(infos.first);
const char* pathLib = infos.second.c_str();
@ -292,19 +283,19 @@ namespace {
return lib;
}
inline void createCDS(const pair<oaScalarName,string>& infos){
inline void createCDS(const pair<oaScalarName,string>& infos,const string& path){
try{
cerr << "Overwriting cds.lib file begin" << endl;
string cdsPath = infos.second + "/cds.lib";
cerr << "Overwriting cds.lib file begin " << endl;
string cdsPath = path + "/cds.lib";
oaLibDefList* ldl = oaLibDefList::get( cdsPath.c_str(), 'a');
assert(ldl);
assert(ldl->isValid());
if(!oaLibDef::find(ldl, infos.first))
oaLibDef::create(ldl, infos.first, infos.second.c_str());
ldl->save();
ldl->destroy();//claim memory
ldl = NULL;
cerr << "Overwrited cds.lib file end" << endl;
assert(ldl->isValid());
if(!oaLibDef::find(ldl, infos.first))
oaLibDef::create(ldl, infos.first, infos.second.c_str());
ldl->save();
ldl->destroy();//claim memory
ldl = NULL;
cerr << "Overwrited cds.lib file end" << endl;
}catch(oaException& e){
cerr << "ERROR cds: " << e.getMsg() << endl;
exit(-2);
@ -352,7 +343,7 @@ namespace {
}
return findLibraryByNameInLibrary(rootLibrary, libraryName);
}
inline void getAllCells(Library* rootLibrary, set<Cell*>& cellSet) {
for_each_cell(cell, rootLibrary->getCells()) {
cellSet.insert(cell);
@ -391,7 +382,7 @@ namespace {
/**
function helper
*/
*/
inline Library* getOACellLibraries() {
Library* rootLibrary = getRootLibrary();
if (!rootLibrary) {
@ -408,7 +399,7 @@ namespace {
/**
helper function
*/
*/
inline Library* getOADesignLibraries() {
Library* rootLibrary = getRootLibrary();
if (!rootLibrary) {
@ -425,7 +416,7 @@ namespace {
/**
utility to open a design by name
*/
*/
inline oaView* pickView(oaCell* oa_Cell) {
//oacMaskLayout Type is first
oaView* toReturnView = NULL;
@ -452,7 +443,7 @@ namespace {
/**
utility to open a design by name
*/
*/
inline oaDesign* openDesign(const oaNameSpace& oaNS, oaCell* oa_Cell) {
oaView* view = pickView(oa_Cell);
if (view != NULL) {
@ -567,25 +558,25 @@ namespace {
if (instance) {
//cerr << "found " << instance << endl;
oaPlacementStatus placementStatus= oa_Inst->getPlacementStatus();
//switch (placementStatus) {
// case oacNonePlacementStatus :
// cerr << " none" << endl;
// break;
// case oacUnplacedPlacementStatus :
// cerr << " unplaced" << endl;
// break;
// case oacPlacedPlacementStatus :
// cerr << " placed" << endl;
// break;
// case oacFixedPlacementStatus :
// cerr << " fixed" << endl;
// break;
// default :
// cerr << "other" << endl;
//}
switch (placementStatus) {
case oacNonePlacementStatus :
cerr << " none" << endl;
break;
case oacUnplacedPlacementStatus :
cerr << " unplaced" << endl;
break;
case oacPlacedPlacementStatus :
cerr << " placed" << endl;
break;
case oacFixedPlacementStatus :
cerr << " fixed" << endl;
break;
default :
cerr << "other" << endl;
}
oaPoint instOrigin;
oa_Inst->getOrigin(instOrigin);
//cerr << instOrigin.x() << " " << instOrigin.y() << endl;
cerr << instOrigin.x() << " " << instOrigin.y() << endl;
} else {
cerr << "cannot find " << oaInstStr << endl;
}
@ -617,6 +608,188 @@ namespace {
}
}//end if (cellDesign != NULL)
}
inline oaRect* MakeRect(oaBlock *block,
oaTransform &xform,
oaInt4 xformXoffset,
oaLayer* layerPin){
xform.xOffset() += xformXoffset;
const oaUInt4 lengthPin(3);
const oaUInt4 widthPin(2);
const oaBox boxPin(0, -static_cast<oaInt4>(widthPin/2),
lengthPin, static_cast<oaInt4>(widthPin/2));
return oaRect::create(block,
layerPin->getNumber(),
oacDrawingPurposeType,
oaBox(boxPin, xform));
}
inline void MakeStub(oaBlock *block,
oaPointArray &pa,
oaInt4 endPointXoffset,
oaLayer* layerPin){
pa[1].x() += endPointXoffset;
oaLine::create(block, layerPin->getNumber(), oacDrawingPurposeType, pa);
}
oaString MakeLabel(oaBlock* block,
oaTransform& xform,
const char* label,
oaLayer* layerText){
oaString str;
const oaUInt4 widthPin(2);
xform.yOffset() += 1 + widthPin/2;
oaText* text = oaText::create(block,
layerText->getNumber(),
oacDrawingPurposeType,
label,
xform.offset(),
oacLowerLeftTextAlign,
oacR0,
oacFixedFont,
3);
text->getText(str);
return str;
}
/**
Make a rectangular Pin shape for a Term on a block's symbol.
For the purpose of the schematicSymbol, this pin shape will
be attached to a line "stub extension" sticking out from the
basic symbol shape to represents block's internal Net.
*/
oaPin* MakePinSymbol(oaBlock* block,
oaPoint location,
const char* strNameTerm,
oaInt4 stubLength,
oaOrient rotation,
oaLayer* layerPin,
oaLayer* layerText){
const oaUInt4 lengthPin(3);
const oaUInt4 widthPin(2);
const oaBox boxPin( 0, -static_cast<oaInt4>(widthPin/2),
lengthPin, static_cast<oaInt4>(widthPin/2));
// boxPin is represented here
// Y-axis
// |
// | lengthPin -->
// |_________
// | |
// ----|---------|-------- X-axis
// |_________|
// |
// |
// Assume the location argument is the point on the main symbol
// against which the Pin is to be located, centered vertically (Y-axis)
// on that point, left of the point if it is an INPUT pin and right
// of that point if an OUTPUT pin, moved orthogonally away from the
// edge of the gate symbol by a stub of length stubLength representing
// part of the internal net of the gate to which a Term's Pin is attached.
//
// | |
// | OUT | Y__
// | point o---------|__|
// | | /
// | | /
// | GATE | stubLength
// | |
// A__ | |
// |__|---------o point |
// / | IN |
// / | |
// stubLength | |
// Define oaTransform xform to be the location argument (no rotation)
// begin_skel
oaTransform xform( location, rotation );
// end_skel
static oaPointArray pa(2);
// Set both points in pa[] to the value of the location arg.
// (HINT: The allocation size and number of points attributes are DIFFERENT.)
//
// begin_skel
pa.setNumElements(2);
pa[0] = location;
pa[1] = location;
// end_skel
// Find the term by name (the strNameTerm arg) and set to the term variable
// for reuse later when the Pin is created for that Term.
oaTerm* term = oaTerm::find(block, oaScalarName(oaNativeNS(),strNameTerm));
// Create for the Term:
//
// 1. A "stub" Line from the symbol shape to the Pin shape
// (representing a connection to the Block's internal Net)
//
// The pa[] PointArray has already been set up for this Line with the start
// and end Points both set to the proper location on the edge of the symbol
// Shape. Only the second (endPoint) X value must be moved to the LEFT
// or RIGHT (for Input or Output Pins, respectively). Call MakeStub() passing
// in the block to the right edge of the Pin.
//
// 2. A rectangular Shape to represent the Pin itself
//
// Use the MakeRect() utility function to create the Shape of the Pin
// passing to it the template boxPin from the globals singleton, and the
// Transform declared and initialized above. That Transform will move the
// base boxPin from its 0,0 location to the location point on the edge of the
// symbol shape. Also pass in an X offset from that location that moves
// the pinBox to the left or right, depending on whether it's an Input or
// Output Pin.
//
// 3. The Pin itself using the rectangle just created with the same name
// as the Term (arg passed in). Set the access direction for the Pin to
// enable connections from all directions except that on the "stub side".
// The rectangle must be explicitly added to the Pin.
//
// 4. A Text label for the Pin whose text value is the name of the Term.
// Use the MakeLabel() utility function passing in the strNameTerm and
// Transform (which now represents the left edge of the Pin shape properly located.
oaPin* pin = NULL;
switch (term->getTermType()) {
// If the Pin is an Output type, assume it is on the RIGHT side.
//
// 1. Call MakeStub() with endPointXoffset to the RIGHT by the stubLength.
// 2. Call MakeRect() with an X offset that moves RIGHT by stubLength.
// 3. Construct the oaPin allowing access from top, bottom and right.
// 4. Call MakeLabel().
//
case oacOutputTermType:
case oacInputOutputTermType:
MakeStub(block, pa, stubLength,layerPin);
pin = oaPin::create(term, oacTop|oacBottom|oacRight);
MakeRect(block, xform, stubLength,layerPin)->addToPin(pin);
MakeLabel(block, xform, strNameTerm,layerText);
break;
// If the Pin is an Input type, assume it is on the LEFT side.
//
// 1. Call MakeStub() with endPointXoffset to the LEFT by the stubLength.
// 2. Call MakeRect() with an X offset that moves LEFT by
// (stubLength + lengthPin) if the rotation is oacR0.
// 3. Construct the oaPin allowing access from top, bottom, and left.
// 4. Call MakeLabel().
case oacInputTermType:
default:
MakeStub(block, pa, -stubLength,layerPin);
pin = oaPin::create(term, oacTop|oacBottom|oacLeft);
MakeRect(block,xform,
-stubLength - (rotation == oacR0
? lengthPin : 0 ),
layerPin)->addToPin(pin);
MakeLabel(block, xform, strNameTerm,layerText);
break;
}
return pin;
}//MakePinSymbol
}//end anonymous namespace
#endif//HAVE_OPENACCESS

View File

@ -0,0 +1,662 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-07-30 16:44:00" - OpenAccessDriver.cpp
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
// | =============================================================== |
// | Author : Chistophe Alexandre |
// | E-mail : Christophe.Alexandre@asim.lip6.fr |
// x-----------------------------------------------------------------x
// | Author : Jean-Manuel Caba |
// | E-mail : Jean-Manuel.Caba@asim.lip6.fr |
// x-----------------------------------------------------------------x
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Library.h"
#include "hurricane/Cell.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Segment.h"
#include "hurricane/Pad.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Slice.h"
using namespace Hurricane;
#include "OpenAccess.h"
#include "OpenAccessCommon.h"
namespace {
#ifdef HAVE_OPENACCESS
/**
Class to drive OA to Hurricane
*/
class OADriver {
private:
typedef map<const Library*, oaLib*> Library2OALibMap;
typedef map<const Cell*, oaDesign*> Cell2OADesignMap;
typedef map<Instance*, oaInst*> Instance2OAInstsMap;
typedef map<Layer*, oaPhysicalLayer*> Layer2OAPhysicalLayerMap;
string _path;
oaTech* _oaTech;
Library2OALibMap _library2OALib;
Cell2OADesignMap _cell2OADesign4Netlist;
Cell2OADesignMap _cell2OADesign4Schematic;
Cell2OADesignMap _cell2OADesign4Symbolic;
Cell2OADesignMap _cell2OADesign4Layout;
Instance2OAInstsMap _instance2OAInst;
Layer2OAPhysicalLayerMap _layer2OAPhysicalLayer;
DataBase* _db;
Technology* _technology;
int _layerID;
oaLayer* layerDev;
oaLayer* layerPin;
oaLayer* layerText;
oaLayer* layerWire;
public:
OADriver(const string& path):
_path(path),
_oaTech(NULL),
_library2OALib(),
_cell2OADesign4Netlist(),
_cell2OADesign4Schematic(),
_cell2OADesign4Symbolic(),
_cell2OADesign4Layout(),
_instance2OAInst(),
_layer2OAPhysicalLayer(),
_db(NULL),
_technology(NULL),
_layerID(0) {
_db = DataBase::getDB();
if (!_db) {
throw Error("no database");
}
_technology = _db->getTechnology();
if (!_technology) {
throw Error("no technology");
}
}
~OADriver() {
cerr << "SAVING ALL" << endl;
_oaTech->save();
_oaTech->close();
saveDesignsInMap(_cell2OADesign4Netlist);
saveDesignsInMap(_cell2OADesign4Schematic);
saveDesignsInMap(_cell2OADesign4Symbolic);
saveDesignsInMap(_cell2OADesign4Layout);
for (Library2OALibMap::iterator it = _library2OALib.begin();
it != _library2OALib.end();
++it) {
oaLib* lib = it->second;
lib->close();
}
cerr << "ALL SAVED" << endl;
}
/**
Create an empty oaLib from a Library
no cells are added in this oaLib
all sub Library are also converted.
*/
oaLib* getOALibForLibrary(const Library* library) {
cerr << "getOALibForLibrary" << endl;
assert(library);
Library2OALibMap::iterator it = _library2OALib.find(library);
if (it != _library2OALib.end()) {
return it->second;
}
// 1) create or open library
pair<oaScalarName,string> infos=libInfos(_path,
getString(library->getName()));
oaLib *lib = openOALib(infos);
_library2OALib[library] = lib;
#if 0
// 2) for each cell convert them too : if it's a standard cell library for example
for_each_cell(c ,library->getCells()){
getOADesignForCell(c);
end_for;
}
// 3) also convert each contained library if any
for_each_library(l ,library->getLibraries()){
getOALibForLibrary(l);
end_for;
}
#endif
// 4) create, update library list file
createCDS(infos,_path);
return lib;
}
/**
convert oaLayer from a Layer ...
*/
oaLayer* getOALayerFromLayer(Layer* layer,oaTech* theOATech) {
assert(layer);
Layer2OAPhysicalLayerMap::iterator it = _layer2OAPhysicalLayer.find(layer);
if (it != _layer2OAPhysicalLayer.end()) {
return it->second;
}
assert(theOATech);
// 1) get or create layer
oaString layerName = getString(layer->getName()).c_str();
oaPhysicalLayer* aOALayer = NULL;
aOALayer = oaPhysicalLayer::find(theOATech, layerName, true);
if(aOALayer){
_layer2OAPhysicalLayer[layer] = aOALayer;
return aOALayer;
}
BasicLayer* bLayer = dynamic_cast<BasicLayer*>(layer);
if(bLayer)
aOALayer = oaPhysicalLayer::create(theOATech, layerName, _layerID++,getOAMaterial(bLayer->getMaterial()));
else
aOALayer = oaPhysicalLayer::create(theOATech, layerName, _layerID++);
assert(aOALayer);
_layer2OAPhysicalLayer[layer] = aOALayer;
//create and add layer constraint for Layer specific manufacturing rules
cerr << " o get value for constraint" << endl;
long minSize = Hurricane::DbU::getDb(layer->getMinimalSize());
long minSpace = Hurricane::DbU::getDb(layer->getMinimalSpacing());
long pitch = Hurricane::DbU::getDb(layer->getPitch());
#if 0
cerr << " o create constraint for min size : " << pitch << endl;
oaLayerConstraint* cMinSize = NULL;
try{
cMinSize = oaLayerConstraint::create(aOALayer->getNumber(),
oaLayerConstraintDef::get(oacMinSize),
oaIntValue::create(theOATech,500))
}catch(oaException& e){
cerr << "ERROR oaLayer: " << e.getMsg() << endl;
exit(-2);
}catch(...){
cerr << "ERROR oaLayer: [UNKNOWN]" << endl;
exit(-1);
}
assert(cMinSize);
cerr << " o create constraint for min space" << endl;
oaLayerConstraint* cMinSpace = oaLayerConstraint::create(aOALayer->getNumber(),
oaLayerConstraintDef::get(oacMinSpacing),
oaIntValue::create(theOATech->getLib(),minSpace));
assert(cMinSpace);
cerr << " o create constraint for pitchH" << endl;
oaLayerConstraint* cPitchH = oaLayerConstraint::create(aOALayer->getNumber(),
oaLayerConstraintDef::get(oacHorizontalRouteGridPitch),
oaIntValue::create(theOATech->getLib(),pitch));
assert(cPitchH);
cerr << " o create constraint for pitchV" << endl;
oaLayerConstraint* cPitchV = oaLayerConstraint::create(aOALayer->getNumber(),
oaLayerConstraintDef::get(oacVerticalRouteGridPitch),
oaIntValue::create(theOATech->getLib(),pitch));
assert(cPitchV);
#endif
if(bLayer){
unsigned gdsIInumber = bLayer->getExtractNumber();
}
return aOALayer;
}
/**
create a oaTech from a Hurricane::Technology in it's Library
also create the oaLib corresponding to the Hurricane::Library
containing the Hurricane::Technology
@todo complete with technology info for layers
@see getOALibForLibrary
*/
oaTech* getOATechForTechnology(const Technology* technology,const Library* lib) {
cerr << "createOATechForTechnology" << endl;
assert(technology);
// 1) get or create Library for the techno
assert(lib);
oaLib* techOAlib = getOALibForLibrary(lib);
assert(techOAlib);
// 2) get or create oaTech container
bool created = false;
cerr << "oaTech::find" << endl;
oaTech* theOATech = oaTech::find(techOAlib);
if(!theOATech){
if (oaTech::exists(techOAlib)){
cerr << "oaTech::open" << endl;
theOATech = oaTech::open(techOAlib,'a');
}
if(!theOATech){
cerr << "oaTech::create" << endl;
theOATech = oaTech::create(techOAlib);
created = true;
}
}
assert(techOAlib);
if(created){
theOATech->setDefaultManufacturingGrid(10);
theOATech->setDBUPerUU(oaViewType::get(oacMaskLayout), 2000);
//create and add foundry constraint group for General manufacturing rules
//and add oaSimpleConstraintType too
oaConstraintGroup *cgFoundry = theOATech->getFoundryRules();
/*
add the constraint group LEFDefaultRouteSpec for oa2lef
*/
//first create "utility" layers following :
layerDev = oaPhysicalLayer::create(theOATech, "device", _layerID++);
layerText = oaPhysicalLayer::create(theOATech, "text", _layerID++);
layerPin = oaPhysicalLayer::create(theOATech, "pin", _layerID++);
layerWire = oaPhysicalLayer::create(theOATech, "wire", _layerID++);
}
// get or create physical layer
for_each_layer(layer, technology->getLayers()) {
getOALayerFromLayer(layer,theOATech);
end_for;
}
printOALayers(theOATech);
return theOATech;
}
/**
convert Hurricane::Instance to oaInst ...
*/
oaInst* getOAInstForInstance(Instance* instance,oaBlock* topBlock) {
cerr << "getOAInstForInstance " << instance << endl;
assert(instance);
Instance2OAInstsMap::iterator it = _instance2OAInst.find(instance);
if (it != _instance2OAInst.end()) {
return it->second;
}
assert(topBlock);
// 1) get the master cell for the instance
Cell* masterCell = instance->getMasterCell();
assert(masterCell);
oaDesign* masterDesign = getOADesignForCell(masterCell);
assert(masterDesign);
oaNativeNS ns;
oaScalarName scMasterName;
masterDesign->getCellName(scMasterName);
oaString strMasterName;
scMasterName.get(strMasterName);
oaScalarName scInstName(ns, getString(instance->getName()).c_str());
oaScalarInst* blockInst = oaScalarInst::find(topBlock,
scInstName);
if(!blockInst){
oaTransform transform;
getOATransformFromTransformation(transform, instance->getTransformation());
blockInst = oaScalarInst::create(topBlock, masterDesign, scInstName, transform);
}
_instance2OAInst[instance] = blockInst;
return blockInst;
}
/**
convert Hurricane::plug to oaInstTerm
and add it to if connected.
always return a non NULL value
*/
oaInstTerm* getOAInstTermFromPlug(Plug* plug,oaNet* net){
cerr << "getOAInstTermFromPlug " << plug << endl;
assert(plug);
Instance* instance = plug->getInstance();
Instance2OAInstsMap::iterator it = _instance2OAInst.find(instance);
assert(it != _instance2OAInst.end());
oaInst* blockInst = it->second;
oaInstTerm* instTerm = getInstTerm(blockInst, plug,net);
assert(instTerm);
return instTerm;
}
oaPin* getOAPinFromNet(Net* net,oaNet* blockNet){
cerr << "getOAPinFromNet" << endl;
assert(net);
assert(net->isExternal());
assert(blockNet);
oaNativeNS ns;
oaScalarName scNetName(ns, getString(net->getName()).c_str());
oaTerm* term = oaTerm::find(blockNet->getBlock(), scNetName);
assert(term);
oaPin* pin = oaPin::create(term);
return pin;
}
oaRect* getOARectFromComponent(Component* component,oaBlock* topBlock){
cerr << "getOARectFromComponent" << endl;
assert(component);
assert(topBlock);
oaBox box;
getOABoxForBox(box, component->getBoundingBox());
Layer* layer = (Layer*) component->getLayer();
assert(layer);
oaPhysicalLayer* physLayer = NULL;
Layer2OAPhysicalLayerMap::iterator it = _layer2OAPhysicalLayer.find(layer);
if (it != _layer2OAPhysicalLayer.end()) {
physLayer = it->second;
}
assert(physLayer);
oaLayerNum layerNum = physLayer->getNumber();
oaRect* rect = oaRect::create(topBlock,
layerNum,
oacDrawingPurposeType,
box);
return rect;
}
/**
convert Hurricane::Net to oaNet
always return a non NULL value
*/
oaNet* getOANetFromNet(Net* net,oaBlock* topBlock) {
cerr << "getOANetFromNet " << net << endl;
assert(net);
oaNativeNS ns;
oaScalarName scNetName(ns, getString(net->getName()).c_str());
oaScalarNet* blockNet = NULL;
blockNet = oaScalarNet::find(topBlock, scNetName);
if(blockNet)
return blockNet;
assert(!blockNet);
blockNet = oaScalarNet::create(topBlock, scNetName, getOASigType(net->getType()));
assert(blockNet);
oaScalarTerm::create(blockNet, scNetName, getOATermType(net->getDirection()));
if (net->isExternal()) {
oaPin* pin = getOAPinFromNet(net,blockNet);
Components externalComponents = NetExternalComponents::get(net);
for_each_component(component, externalComponents) {
oaRect* rect = getOARectFromComponent(component,topBlock);
// rect->addToPin(pin);
end_for;
}
}
cerr << " o transformation of plugs" << endl;
for_each_plug(plug, net->getPlugs()) {
getOAInstTermFromPlug(plug,blockNet);
end_for;
}
blockNet->scalarize();
return blockNet;
}
/**
create oaRect for slice ...
*/
void getOARectFromSlice(Slice* slice,oaBlock* topBlock){
cerr << "getOARectFromSlice" << endl;
assert(slice);
assert(topBlock);
for_each_component(component, slice->getComponents()) {
oaRect* rect = getOARectFromComponent(component,topBlock);
end_for;
}
}
/**
Create initial oaDesign from the cell and save it as a netlist view
*/
oaDesign* createOAasNetlist(const Cell* cell) {
cerr << "createNetlist " << cell << endl;
assert(cell);
Cell2OADesignMap::iterator it = _cell2OADesign4Netlist.find(cell);
if (it != _cell2OADesign4Netlist.end()) {
return it->second;
}
// 1) get the lib containing the cell
oaNativeNS ns;
oaLib* lib = getOALibForLibrary(cell->getLibrary());
assert(lib);
// 2) create a netlist CellView of the cell
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "netlist");
oaScalarName scNameLib;
lib->getName(scNameLib);
cerr << "oaDesign::open for netlist view" << endl;
oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, oaViewType::get(oacNetlist), 'a');
_cell2OADesign4Netlist[cell] = designCellView;
// 3) create oaBlock singleton where we will do all the work
oaBlock* topBlock = designCellView->getTopBlock();
if(!topBlock){
cerr << "oaBlock::create for netlist view" << endl;
topBlock = oaBlock::create(designCellView);
}
assert(topBlock);
// 4) convert each OA object
cerr << "transformation of instances" << endl;
for_each_instance(instance, cell->getInstances()){
getOAInstForInstance(instance,topBlock);
end_for;
}
cerr << "transformation of nets" << endl;
for_each_net(net, cell->getNets()){
getOANetFromNet(net,topBlock);
end_for;
}
return designCellView;
}
/**
Add symbol view to previous view ...
*/
oaDesign* addSymbol(const Cell* cell,oaDesign* previous) {
cerr << "addSymbol" << cell << endl;
assert(cell);
assert(previous);
Cell2OADesignMap::iterator it = _cell2OADesign4Symbolic.find(cell);
if (it != _cell2OADesign4Symbolic.end()) {
return it->second;
}
oaNativeNS ns;
oaLib* lib = getOALibForLibrary(cell->getLibrary());
assert(lib);
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "symbolic");
oaScalarName scNameLib;
lib->getName(scNameLib);
// create a symbolic CellView of the cell
oaViewType* vType = oaViewType::get(oacSchematicSymbol);
cerr << "oaDesign::open for symbolic view" << endl;
oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, vType, 'a');
_cell2OADesign4Symbolic[cell] = designCellView;
// get module or embed previous module
oaModule* topMod = NULL;
topMod = designCellView->getTopModule();
if(!topMod){
topMod = oaModule::embed(designCellView, previous);
designCellView->setTopModule(topMod);
}
oaBlock *topBlock = designCellView->getTopBlock();
assert(topBlock);
return designCellView;
}
/**
Add schematic view to previous view ...
*/
oaDesign* addSchematic(const Cell* cell,oaDesign* previous) {
cerr << "addSchematic" << cell << endl;
assert(cell);
assert(previous);
Cell2OADesignMap::iterator it = _cell2OADesign4Schematic.find(cell);
if (it != _cell2OADesign4Schematic.end()) {
return it->second;
}
oaNativeNS ns;
oaLib* lib = getOALibForLibrary(cell->getLibrary());
assert(lib);
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "schematic");
oaScalarName scNameLib;
lib->getName(scNameLib);
// create a schematic CellView of the cell
oaViewType* vType = oaViewType::get(oacSchematic);
cerr << "oaDesign::open for schematic view" << endl;
oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, vType, 'a');
_cell2OADesign4Schematic[cell] = designCellView;
// get module or embed previous module
oaModule* topMod = NULL;
topMod = designCellView->getTopModule();
if(!topMod){
topMod = oaModule::embed(designCellView, previous);
designCellView->setTopModule(topMod);
}
oaBlock *topBlock = designCellView->getTopBlock();
assert(topBlock);
return designCellView;
}
/**
Add layout view to previous view ...
*/
oaDesign* addLayout(const Cell* cell,oaDesign* previous) {
cerr << "addLayout" << cell << endl;
assert(cell);
assert(previous);
Cell2OADesignMap::iterator it = _cell2OADesign4Layout.find(cell);
if (it != _cell2OADesign4Layout.end()) {
return it->second;
}
oaNativeNS ns;
oaLib* lib = getOALibForLibrary(cell->getLibrary());
assert(lib);
oaScalarName scNameDesign(ns, getString(cell->getName()).c_str());
oaScalarName scNameView(ns, "layout");
oaScalarName scNameLib;
lib->getName(scNameLib);
// create a layout CellView of the cell
oaViewType* vType = oaViewType::get(oacMaskLayout);
cerr << "oaDesign::open for layout view" << endl;
oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, vType, 'a');
_cell2OADesign4Layout[cell] = designCellView;
// get module or embed previous module
oaModule* topMod = NULL;
topMod = designCellView->getTopModule();
if(!topMod){
topMod = oaModule::embed(designCellView, previous);
designCellView->setTopModule(topMod);
}
oaBlock *topBlock = designCellView->getTopBlock();
assert(topBlock);
cerr << "transformation of slices" << endl;
for_each_slice(slice, cell->getSlices()){
getOARectFromSlice(slice,topBlock);
end_for;
}
return designCellView;
}
/**
Convert a Cell to OA designs ...
*/
oaDesign* getOADesignForCell(const Cell* cell) {
cerr << "getOADesignForCell " << cell << endl;
assert(cell);
// 1) get technology
if(!_oaTech)
_oaTech = getOATechForTechnology(_technology,cell->getLibrary());
// 2) create OA structure ...
oaDesign* netlistView = createOAasNetlist(cell);
assert(netlistView);
oaCell* c1 = OADesignToOACell(netlistView);
assert(c1);
oaDesign* symbolicView = addSymbol(cell,netlistView);
assert(symbolicView);
oaCell* c2 = OADesignToOACell(symbolicView);
assert(c2);
oaDesign* schematicView = addSchematic(cell,symbolicView);
assert(schematicView);
oaCell* c3 = OADesignToOACell(schematicView);
assert(c3);
oaDesign* layoutView = addLayout(cell,schematicView);
assert(layoutView);
oaCell* c4 = OADesignToOACell(layoutView);
assert(c4);
//3) we check it's the same oaCell for all designs
assert(c1 == c2 && c2 == c3 && c3 == c4);
return netlistView;
}
oaCell* getOACellForCell(const Cell* cell) {
return OADesignToOACell( getOADesignForCell(cell) );
}
};//OADriver class
#endif
}//namespace
namespace CRL {
oaCell* OpenAccess::oaDriver(const string& path, Cell* cell) {
#ifdef HAVE_OPENACCESS
//for the moment a driver for hurricaneAMS
//save the Cell only and all used Cell
oaCell* convertedCell = NULL;
cerr << "Saving " << cell << " in " << path << endl;
try {
oaDesignInit(oacAPIMajorRevNumber,
oacAPIMinorRevNumber,
oacDataModelRevNumber);
OADriver oaDriver(path);
convertedCell = oaDriver.getOACellForCell(cell);
}catch (oaException &e) {
cerr << "OA::ERROR => " << e.getMsg() << endl;
exit(1);
}catch(std::exception& e){
cerr << "STD::ERROR => " << e.what() << endl;
exit(2);
}
return convertedCell;
#else
cerr << "\nDummy OpenAccess driver call for " << path << endl;
return NULL;
#endif
}
}

View File

@ -1,5 +1,5 @@
// -*-compile-command:"cd ../../../../.. && make"-*-
// Time-stamp: "2010-07-26 16:16:18" - OpenAccessParser.cpp
// Time-stamp: "2010-07-28 15:44:58" - OpenAccessParser.cpp
// x-----------------------------------------------------------------x
// | This file is part of the hurricaneAMS Software. |
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
@ -344,7 +344,6 @@ namespace {
cout << "ERROR: " << excp.getMsg() << endl;
exit(1);
}
}
void getDesigns(set<Cell*>& designCellSet) {

View File

@ -1,16 +1,15 @@
all:
./compile.sh
run:
cd x86_64/usr/local/bin && ./testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
run:
./x86_64/usr/local/bin/testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA 2>&1 | tee err.log
debug:
cd x86_64/usr/local/bin && gdb -args ./testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
debug:
gdb -args ./x86_64/usr/local/bin/testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
ddd:
cd x86_64/usr/local/bin && ddd -args ./testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
ddd:
ddd -args ./x86_64/usr/local/bin/testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
rmtmp:
rm -rf /tmp/*

View File

@ -29,6 +29,7 @@ using namespace CRL;
#include "hurricaneAMS/devices/SimpleCurrentMirror.h"
#include "crlcore/GdsDriver.h"
#include "crlcore/CifDriver.h"
#include "crlcore/OADriver.h"
namespace {
@ -44,9 +45,13 @@ void testCell(Cell* dev,char* pathToTest){
return;
}
system((string("mkdir -p ") + string(pathToTest)).c_str());
cerr << "driving GDS" << endl;
GdsDriver(dev).save(string(pathToTest) + "/" + getString(dev->getName()) + ".gds");
cerr << "driving CIF" << endl;
CifDriver(dev).save(string(pathToTest) + "/" + getString(dev->getName()) + ".cif");
cerr << "driving OA" << endl;
OADriver(dev).save(string(pathToTest) + "/OAdrive");
}