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"-*-
|
// -*-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
|
// x-----------------------------------------------------------------x
|
||||||
// | This file is part of the hurricaneAMS Software. |
|
// | This file is part of the hurricaneAMS Software. |
|
||||||
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
|
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
|
||||||
|
@ -35,7 +35,6 @@ namespace {
|
||||||
return the oaString representing its name
|
return the oaString representing its name
|
||||||
*/
|
*/
|
||||||
inline oaString getDesignName(oaDesign* design) {
|
inline oaString getDesignName(oaDesign* design) {
|
||||||
cerr << "getDesignName" << endl;
|
|
||||||
assert(design);
|
assert(design);
|
||||||
oaNativeNS ns;
|
oaNativeNS ns;
|
||||||
oaString libName, cellName, viewName;
|
oaString libName, cellName, viewName;
|
||||||
|
@ -52,7 +51,6 @@ namespace {
|
||||||
@todo remove when not needed anymore
|
@todo remove when not needed anymore
|
||||||
*/
|
*/
|
||||||
inline void printBlockTerms(oaBlock* block) {
|
inline void printBlockTerms(oaBlock* block) {
|
||||||
cerr << "printBlockTerms" << endl;
|
|
||||||
assert(block);
|
assert(block);
|
||||||
oaNativeNS ns;
|
oaNativeNS ns;
|
||||||
oaDesign* design = block->getDesign();
|
oaDesign* design = block->getDesign();
|
||||||
|
@ -71,7 +69,6 @@ namespace {
|
||||||
@todo verify
|
@todo verify
|
||||||
*/
|
*/
|
||||||
inline oaMaterial getOAMaterial(const BasicLayer::Material& material) {
|
inline oaMaterial getOAMaterial(const BasicLayer::Material& material) {
|
||||||
cerr << "getOAMaterial" << endl;
|
|
||||||
switch ( material.getCode() ) {
|
switch ( material.getCode() ) {
|
||||||
case BasicLayer::Material::nWell: return oacNWellMaterial;
|
case BasicLayer::Material::nWell: return oacNWellMaterial;
|
||||||
case BasicLayer::Material::pWell: return oacPWellMaterial;
|
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 ...
|
Convertion helper for Net convertion ...
|
||||||
@todo verify
|
@todo verify
|
||||||
*/
|
*/
|
||||||
inline oaTermType getOATermType(const Net::Direction& direction) {
|
inline oaTermType getOATermType(const Net::Direction& direction) {
|
||||||
cerr << "getOATermType" << endl;
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Net::Direction::IN:
|
case Net::Direction::IN:
|
||||||
return oacInputTermType;
|
return oacInputTermType;
|
||||||
|
@ -117,7 +138,6 @@ namespace {
|
||||||
@todo verify
|
@todo verify
|
||||||
*/
|
*/
|
||||||
inline oaSigType getOASigType(const Net::Type& type) {
|
inline oaSigType getOASigType(const Net::Type& type) {
|
||||||
cerr << "getOASigType" << endl;
|
|
||||||
switch (type.getCode()) {
|
switch (type.getCode()) {
|
||||||
case Net::Type::LOGICAL:
|
case Net::Type::LOGICAL:
|
||||||
return oacSignalSigType;
|
return oacSignalSigType;
|
||||||
|
@ -136,9 +156,8 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convertion helper ...
|
Convertion helper ...
|
||||||
*/
|
*/
|
||||||
inline oaOrient getOAOrientFromOrientation(const Transformation::Orientation& orientation) {
|
inline oaOrient getOAOrientFromOrientation(const Transformation::Orientation& orientation) {
|
||||||
cerr << "getOAOrientFromOrientation" << endl;
|
|
||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
case Transformation::Orientation::ID:
|
case Transformation::Orientation::ID:
|
||||||
return oacR0;
|
return oacR0;
|
||||||
|
@ -163,9 +182,8 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convertion helper ...
|
Convertion helper ...
|
||||||
*/
|
*/
|
||||||
inline void getOATransformFromTransformation(oaTransform& transform, const Transformation& transformation) {
|
inline void getOATransformFromTransformation(oaTransform& transform, const Transformation& transformation) {
|
||||||
cerr << "getOATransformFromTransformation" << endl;
|
|
||||||
transform.set(transformation.getTx(),
|
transform.set(transformation.getTx(),
|
||||||
transformation.getTy(),
|
transformation.getTy(),
|
||||||
getOAOrientFromOrientation(transformation.getOrientation()));
|
getOAOrientFromOrientation(transformation.getOrientation()));
|
||||||
|
@ -173,18 +191,17 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convertion helper ...
|
Convertion helper ...
|
||||||
*/
|
*/
|
||||||
inline void getOABoxForBox(oaBox& box, const Box& hbox) {
|
inline void getOABoxForBox(oaBox& box, const Box& hbox) {
|
||||||
cerr << "getOABoxForBox" << endl;
|
cerr << "getOABoxForBox" << endl;
|
||||||
box.set(hbox.getXMin(), hbox.getYMin(), hbox.getXMax(), hbox.getYMax());
|
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
|
always return a non NULL value
|
||||||
*/
|
*/
|
||||||
inline oaInstTerm* getInstTerm(oaInst* inst, Plug* plug,oaNet* net) {
|
inline oaInstTerm* getInstTerm(oaInst* inst, Plug* plug,oaNet* net) {
|
||||||
cerr << "getInstTerm" << endl;
|
|
||||||
assert(inst);
|
assert(inst);
|
||||||
assert(plug);
|
assert(plug);
|
||||||
oaNativeNS ns;
|
oaNativeNS ns;
|
||||||
|
@ -225,7 +242,6 @@ namespace {
|
||||||
print the oaLayera in a oaTech ...
|
print the oaLayera in a oaTech ...
|
||||||
*/
|
*/
|
||||||
inline void printOALayers(oaTech* theOATech){
|
inline void printOALayers(oaTech* theOATech){
|
||||||
cerr << "printOALayers" << endl;
|
|
||||||
assert(theOATech);
|
assert(theOATech);
|
||||||
oaIter<oaLayer> lIter(theOATech->getLayers());
|
oaIter<oaLayer> lIter(theOATech->getLayers());
|
||||||
while(oaLayer* l = lIter.getNext()){
|
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
|
generate info from library name
|
||||||
*/
|
*/
|
||||||
inline pair<oaScalarName,string> libInfos(const string& path,
|
inline pair<oaScalarName,string> libInfos(const string& path,
|
||||||
const string& libName){
|
const string& libName){
|
||||||
oaNativeNS ns;
|
oaNativeNS ns;
|
||||||
|
@ -274,7 +265,7 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
open oaLib with the info gathered by libPath function
|
open oaLib with the info gathered by libPath function
|
||||||
*/
|
*/
|
||||||
inline oaLib* openOALib(const pair<oaScalarName,string>& infos){
|
inline oaLib* openOALib(const pair<oaScalarName,string>& infos){
|
||||||
oaLib *lib = oaLib::find(infos.first);
|
oaLib *lib = oaLib::find(infos.first);
|
||||||
const char* pathLib = infos.second.c_str();
|
const char* pathLib = infos.second.c_str();
|
||||||
|
@ -292,19 +283,19 @@ namespace {
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void createCDS(const pair<oaScalarName,string>& infos){
|
inline void createCDS(const pair<oaScalarName,string>& infos,const string& path){
|
||||||
try{
|
try{
|
||||||
cerr << "Overwriting cds.lib file begin" << endl;
|
cerr << "Overwriting cds.lib file begin " << endl;
|
||||||
string cdsPath = infos.second + "/cds.lib";
|
string cdsPath = path + "/cds.lib";
|
||||||
oaLibDefList* ldl = oaLibDefList::get( cdsPath.c_str(), 'a');
|
oaLibDefList* ldl = oaLibDefList::get( cdsPath.c_str(), 'a');
|
||||||
assert(ldl);
|
assert(ldl);
|
||||||
assert(ldl->isValid());
|
assert(ldl->isValid());
|
||||||
if(!oaLibDef::find(ldl, infos.first))
|
if(!oaLibDef::find(ldl, infos.first))
|
||||||
oaLibDef::create(ldl, infos.first, infos.second.c_str());
|
oaLibDef::create(ldl, infos.first, infos.second.c_str());
|
||||||
ldl->save();
|
ldl->save();
|
||||||
ldl->destroy();//claim memory
|
ldl->destroy();//claim memory
|
||||||
ldl = NULL;
|
ldl = NULL;
|
||||||
cerr << "Overwrited cds.lib file end" << endl;
|
cerr << "Overwrited cds.lib file end" << endl;
|
||||||
}catch(oaException& e){
|
}catch(oaException& e){
|
||||||
cerr << "ERROR cds: " << e.getMsg() << endl;
|
cerr << "ERROR cds: " << e.getMsg() << endl;
|
||||||
exit(-2);
|
exit(-2);
|
||||||
|
@ -391,7 +382,7 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
function helper
|
function helper
|
||||||
*/
|
*/
|
||||||
inline Library* getOACellLibraries() {
|
inline Library* getOACellLibraries() {
|
||||||
Library* rootLibrary = getRootLibrary();
|
Library* rootLibrary = getRootLibrary();
|
||||||
if (!rootLibrary) {
|
if (!rootLibrary) {
|
||||||
|
@ -408,7 +399,7 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
helper function
|
helper function
|
||||||
*/
|
*/
|
||||||
inline Library* getOADesignLibraries() {
|
inline Library* getOADesignLibraries() {
|
||||||
Library* rootLibrary = getRootLibrary();
|
Library* rootLibrary = getRootLibrary();
|
||||||
if (!rootLibrary) {
|
if (!rootLibrary) {
|
||||||
|
@ -425,7 +416,7 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
utility to open a design by name
|
utility to open a design by name
|
||||||
*/
|
*/
|
||||||
inline oaView* pickView(oaCell* oa_Cell) {
|
inline oaView* pickView(oaCell* oa_Cell) {
|
||||||
//oacMaskLayout Type is first
|
//oacMaskLayout Type is first
|
||||||
oaView* toReturnView = NULL;
|
oaView* toReturnView = NULL;
|
||||||
|
@ -452,7 +443,7 @@ namespace {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
utility to open a design by name
|
utility to open a design by name
|
||||||
*/
|
*/
|
||||||
inline oaDesign* openDesign(const oaNameSpace& oaNS, oaCell* oa_Cell) {
|
inline oaDesign* openDesign(const oaNameSpace& oaNS, oaCell* oa_Cell) {
|
||||||
oaView* view = pickView(oa_Cell);
|
oaView* view = pickView(oa_Cell);
|
||||||
if (view != NULL) {
|
if (view != NULL) {
|
||||||
|
@ -567,25 +558,25 @@ namespace {
|
||||||
if (instance) {
|
if (instance) {
|
||||||
//cerr << "found " << instance << endl;
|
//cerr << "found " << instance << endl;
|
||||||
oaPlacementStatus placementStatus= oa_Inst->getPlacementStatus();
|
oaPlacementStatus placementStatus= oa_Inst->getPlacementStatus();
|
||||||
//switch (placementStatus) {
|
switch (placementStatus) {
|
||||||
// case oacNonePlacementStatus :
|
case oacNonePlacementStatus :
|
||||||
// cerr << " none" << endl;
|
cerr << " none" << endl;
|
||||||
// break;
|
break;
|
||||||
// case oacUnplacedPlacementStatus :
|
case oacUnplacedPlacementStatus :
|
||||||
// cerr << " unplaced" << endl;
|
cerr << " unplaced" << endl;
|
||||||
// break;
|
break;
|
||||||
// case oacPlacedPlacementStatus :
|
case oacPlacedPlacementStatus :
|
||||||
// cerr << " placed" << endl;
|
cerr << " placed" << endl;
|
||||||
// break;
|
break;
|
||||||
// case oacFixedPlacementStatus :
|
case oacFixedPlacementStatus :
|
||||||
// cerr << " fixed" << endl;
|
cerr << " fixed" << endl;
|
||||||
// break;
|
break;
|
||||||
// default :
|
default :
|
||||||
// cerr << "other" << endl;
|
cerr << "other" << endl;
|
||||||
//}
|
}
|
||||||
oaPoint instOrigin;
|
oaPoint instOrigin;
|
||||||
oa_Inst->getOrigin(instOrigin);
|
oa_Inst->getOrigin(instOrigin);
|
||||||
//cerr << instOrigin.x() << " " << instOrigin.y() << endl;
|
cerr << instOrigin.x() << " " << instOrigin.y() << endl;
|
||||||
} else {
|
} else {
|
||||||
cerr << "cannot find " << oaInstStr << endl;
|
cerr << "cannot find " << oaInstStr << endl;
|
||||||
}
|
}
|
||||||
|
@ -617,6 +608,188 @@ namespace {
|
||||||
}
|
}
|
||||||
}//end if (cellDesign != NULL)
|
}//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
|
}//end anonymous namespace
|
||||||
|
|
||||||
#endif//HAVE_OPENACCESS
|
#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"-*-
|
// -*-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
|
// x-----------------------------------------------------------------x
|
||||||
// | This file is part of the hurricaneAMS Software. |
|
// | This file is part of the hurricaneAMS Software. |
|
||||||
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
|
// | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved |
|
||||||
|
@ -344,7 +344,6 @@ namespace {
|
||||||
cout << "ERROR: " << excp.getMsg() << endl;
|
cout << "ERROR: " << excp.getMsg() << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void getDesigns(set<Cell*>& designCellSet) {
|
void getDesigns(set<Cell*>& designCellSet) {
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
./compile.sh
|
./compile.sh
|
||||||
|
|
||||||
run:
|
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:
|
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:
|
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:
|
rmtmp:
|
||||||
rm -rf /tmp/*
|
rm -rf /tmp/*
|
||||||
|
|
|
@ -29,6 +29,7 @@ using namespace CRL;
|
||||||
#include "hurricaneAMS/devices/SimpleCurrentMirror.h"
|
#include "hurricaneAMS/devices/SimpleCurrentMirror.h"
|
||||||
|
|
||||||
#include "crlcore/GdsDriver.h"
|
#include "crlcore/GdsDriver.h"
|
||||||
|
#include "crlcore/CifDriver.h"
|
||||||
#include "crlcore/OADriver.h"
|
#include "crlcore/OADriver.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -44,9 +45,13 @@ void testCell(Cell* dev,char* pathToTest){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
system((string("mkdir -p ") + string(pathToTest)).c_str());
|
system((string("mkdir -p ") + string(pathToTest)).c_str());
|
||||||
|
|
||||||
cerr << "driving GDS" << endl;
|
cerr << "driving GDS" << endl;
|
||||||
GdsDriver(dev).save(string(pathToTest) + "/" + getString(dev->getName()) + ".gds");
|
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;
|
cerr << "driving OA" << endl;
|
||||||
OADriver(dev).save(string(pathToTest) + "/OAdrive");
|
OADriver(dev).save(string(pathToTest) + "/OAdrive");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue