re-add OpenAccessDriver.cpp Oops, and at last .cds file are generated the way we want them to ...
This commit is contained in:
parent
2b78ecef1a
commit
0b9a17f85d
|
@ -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 |
|
||||
|
@ -35,7 +35,6 @@ namespace {
|
|||
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;
|
||||
|
@ -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;
|
||||
|
@ -138,7 +158,6 @@ namespace {
|
|||
Convertion helper ...
|
||||
*/
|
||||
inline oaOrient getOAOrientFromOrientation(const Transformation::Orientation& orientation) {
|
||||
cerr << "getOAOrientFromOrientation" << endl;
|
||||
switch (orientation) {
|
||||
case Transformation::Orientation::ID:
|
||||
return oacR0;
|
||||
|
@ -165,7 +184,6 @@ namespace {
|
|||
Convertion helper ...
|
||||
*/
|
||||
inline void getOATransformFromTransformation(oaTransform& transform, const Transformation& transformation) {
|
||||
cerr << "getOATransformFromTransformation" << endl;
|
||||
transform.set(transformation.getTx(),
|
||||
transformation.getTy(),
|
||||
getOAOrientFromOrientation(transformation.getOrientation()));
|
||||
|
@ -180,11 +198,10 @@ namespace {
|
|||
}
|
||||
|
||||
/**
|
||||
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,31 +251,6 @@ 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
|
||||
*/
|
||||
|
@ -292,10 +283,10 @@ 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());
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
|
||||
|
||||
all:
|
||||
./compile.sh
|
||||
|
||||
run:
|
||||
cd x86_64/usr/local/bin && ./testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
|
||||
./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
|
||||
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 -args ./x86_64/usr/local/bin/testOAWrapper /asim/chams/etc/chams/config.freePDK45.xml /tmp/testOA
|
||||
|
||||
rmtmp:
|
||||
rm -rf /tmp/*
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue