diff --git a/crlcore/src/ccore/openaccess/Makefile b/crlcore/src/ccore/openaccess/Makefile new file mode 100644 index 00000000..3b8c67d9 --- /dev/null +++ b/crlcore/src/ccore/openaccess/Makefile @@ -0,0 +1,3 @@ + +all: + cd ../../../../.. && make diff --git a/crlcore/src/ccore/openaccess/OpenAccessWrapper.cpp b/crlcore/src/ccore/openaccess/OpenAccessWrapper.cpp index 7bd467d8..fd45a861 100644 --- a/crlcore/src/ccore/openaccess/OpenAccessWrapper.cpp +++ b/crlcore/src/ccore/openaccess/OpenAccessWrapper.cpp @@ -1,5 +1,5 @@ // -*-compile-command:"cd ../../../../.. && make"-*- -// Time-stamp: "2010-07-07 16:25:24" - OpenAccessWrapper.cpp +// Time-stamp: "2010-07-15 17:35:58" - OpenAccessWrapper.cpp // x-----------------------------------------------------------------x // | This file is part of the hurricaneAMS Software. | // | Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved | @@ -29,10 +29,12 @@ using namespace oa; #include "hurricane/Segment.h" #include "hurricane/Pad.h" #include "hurricane/BasicLayer.h" +#include "hurricane/Slice.h" using namespace Hurricane; #include "OpenAccessWrapper.h" +#undef assert #define assert(cond) if (! (cond) ) throw Error("assertion failed : " + string( #cond ) ) //#define assert(cond) @@ -41,6 +43,10 @@ namespace { #ifdef HAVE_OPENACCESS + /** + giving a oaDesign pointer that should be not NULL + return the oaString representing its name + */ oaString getDesignName(oaDesign* design) { cerr << "getDesignName" << endl; assert(design); @@ -53,6 +59,11 @@ namespace { return designName; } + /** + giving a oaBlock + print the connectivity, mainly used for debug purpose ... + @todo remove when not needed anymore + */ void printBlockTerms(oaBlock* block) { cerr << "printBlockTerms" << endl; assert(block); @@ -69,6 +80,7 @@ namespace { } /** + Convert material from Hurricane to OA ... @todo verify */ oaMaterial getOAMaterial(const BasicLayer::Material& material) { @@ -90,6 +102,7 @@ namespace { } /** + Convertion helper for Net convertion ... @todo verify */ oaTermType getOATermType(const Net::Direction& direction) { @@ -111,6 +124,7 @@ namespace { } /** + Convertion helper for Net convertion ... @todo verify */ oaSigType getOASigType(const Net::Type& type) { @@ -167,7 +181,11 @@ namespace { box.set(hbox.getXMin(), hbox.getYMin(), hbox.getXMax(), hbox.getYMax()); } - oaInstTerm* getInstTerm(oaInst* inst, Plug* plug) { + /** + Create InstTerm representing connection of nets ... + always return a non NULL value + */ + oaInstTerm* getInstTerm(oaInst* inst, Plug* plug,oaNet* net) { cerr << "getInstTerm" << endl; assert(inst); assert(plug); @@ -185,10 +203,26 @@ namespace { assert(term); cerr << "looking for " << plug->getName() << endl; printBlockTerms(masterBlock); - instTerm = oaInstTerm::create(NULL, inst, term); + cerr << "oaInstTerm::create" << endl; + instTerm = oaInstTerm::create(net, inst, term); + assert(instTerm); return instTerm; } + /** + save design stored in a map + */ + void saveDesignsInMap(map cell2OAdesign){ + for (map::iterator it = cell2OAdesign.begin(); + it != cell2OAdesign.end(); + ++it) { + cerr << it->first << endl; + oaDesign* design = it->second; + design->save(); + design->close(); + } + } + class OADriver { private: typedef map Library2OALibMap; @@ -199,24 +233,30 @@ namespace { string _path; oaTech* _oaTech; - Library2OALibMap _library2OALibMap; - Cell2OADesignMap _cell2OADesign4SchematicMap; - Cell2OADesignMap _cell2OADesign4LayoutMap; - Instance2OAInstsMap _instance2OAInstMap; - Layer2OAPhysicalLayerMap _layer2OAPhysicalLayerMap; + Library2OALibMap _library2OALib; + Cell2OADesignMap _cell2OADesign4Netlist; + Cell2OADesignMap _cell2OADesign4Schematic; + Cell2OADesignMap _cell2OADesign4Symbolic; + Cell2OADesignMap _cell2OADesign4Layout; + Instance2OAInstsMap _instance2OAInst; + Layer2OAPhysicalLayerMap _layer2OAPhysicalLayer; DataBase* _db; Technology* _technology; + int _layerID; public: OADriver(const string& path): _path(path), _oaTech(NULL), - _library2OALibMap(), - _cell2OADesign4SchematicMap(), - _cell2OADesign4LayoutMap(), - _instance2OAInstMap(), - _layer2OAPhysicalLayerMap(), + _library2OALib(), + _cell2OADesign4Netlist(), + _cell2OADesign4Schematic(), + _cell2OADesign4Symbolic(), + _cell2OADesign4Layout(), + _instance2OAInst(), + _layer2OAPhysicalLayer(), _db(NULL), - _technology(NULL) { + _technology(NULL), + _layerID(0) { _db = DataBase::getDB(); if (!_db) { throw Error("no database"); @@ -231,25 +271,12 @@ namespace { cerr << "SAVING ALL" << endl; _oaTech->save(); _oaTech->close(); - for (Cell2OADesignMap::iterator it = _cell2OADesign4SchematicMap.begin(); - it != _cell2OADesign4SchematicMap.end(); - ++it) { - cerr << it->first << endl; - oaDesign* design = it->second; - design->save(); - design->close(); - } - for (Cell2OADesignMap::iterator it = _cell2OADesign4LayoutMap.begin(); - it != _cell2OADesign4LayoutMap.end(); - ++it) { - cerr << it->first << endl; - oaDesign* design = it->second; - design->save(); - design->close(); - } - - for (Library2OALibMap::iterator it = _library2OALibMap.begin(); - it != _library2OALibMap.end(); + saveDesignsInMap(_cell2OADesign4Netlist); + saveDesignsInMap(_cell2OADesign4Schematic); + saveDesignsInMap(_cell2OADesign4Symbolic); + saveDesignsInMap(_cell2OADesign4Layout); + for (Library2OALibMap::iterator it = _library2OALib.begin(); + it != _library2OALib.end(); ++it) { oaLib* lib = it->second; lib->close(); @@ -257,10 +284,16 @@ namespace { 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; - Library2OALibMap::iterator it = _library2OALibMap.find(library); - if (it != _library2OALibMap.end()) { + assert(library); + Library2OALibMap::iterator it = _library2OALib.find(library); + if (it != _library2OALib.end()) { return it->second; } oaNativeNS ns; @@ -274,119 +307,179 @@ namespace { cerr << "Creating new Library for Lib name=" << strNameLib << " to filesystem path=" << strPathLib << endl; - oaLib *lib = NULL;//oaLib::find(scNameLib); -// if (!lib) { -// if (oaLib::exists(strPathLib.c_str())){ -// lib = oaLib::open(scNameLib, strPathLib.c_str()); -// } - string cmd = "rm -rf "+strPathLib+"; mkdir -p "+strPathLib; - system(cmd.c_str()); -// oaLib* lib = oaLib::create(scNameLib, strPathLib.c_str(), oacSharedLibMode, "oaDMFileSys"); -// if(!lib) - lib = oaLib::create(scNameLib, strPathLib.c_str()); -// } - - assert(lib); - assert(lib->isValid()); - - if(!_oaTech) - _oaTech = createOATechForTechnology(_technology,lib); - - assert(_oaTech); - - _library2OALibMap[library] = lib; - return lib; - } - - /** - @todo complete with technology info for layers - */ - oaTech* createOATechForTechnology(const Technology* technology,oaLib* lib) { - cerr << "createOATechForTechnology" << endl; - oaTech* theOATech = oaTech::create(lib); - theOATech->setDefaultManufacturingGrid(10); - theOATech->setDBUPerUU(oaViewType::get(oacMaskLayout), 1000); - - int layerID=0; - for_each_layer(layer, technology->getLayers()) { - oaString layerName = getString(layer->getName()).c_str(); - oaPhysicalLayer* aOALayer = NULL; - BasicLayer* bLayer = dynamic_cast(layer); - if(bLayer) - aOALayer = oaPhysicalLayer::create(theOATech, layerName, layerID++,getOAMaterial(bLayer->getMaterial())); - else - aOALayer = oaPhysicalLayer::create(theOATech, layerName, layerID++); - assert(aOALayer); - - _layer2OAPhysicalLayerMap[layer] = aOALayer; - DbU::Unit minSize = layer->getMinimalSize(); - DbU::Unit minSpace = layer->getMinimalSpacing(); - DbU::Unit pitch = layer->getPitch(); - end_for; - } - - for_each_basic_layer(basicLayer, technology->getBasicLayers()) { - Layer2OAPhysicalLayerMap::iterator it = _layer2OAPhysicalLayerMap.find((Layer*)(basicLayer)); - if (it != _layer2OAPhysicalLayerMap.end()) { - oaPhysicalLayer* oaLayer = it->second; - unsigned gdsIInumber = basicLayer->getExtractNumber(); + cerr << "oaLib::find" << endl; + oaLib *lib = oaLib::find(scNameLib); + if (!lib) { + if (oaLib::exists(strPathLib.c_str())){ + cerr << "oaLib::open" << endl; + lib = oaLib::open(scNameLib, strPathLib.c_str()); + }else{ + string cmd = "mkdir -p "+strPathLib; + system(cmd.c_str()); + } + if(!lib){ + cerr << "oaLib::create" << endl; + lib = oaLib::create(scNameLib, strPathLib.c_str()); } - end_for; } - assert(theOATech != NULL); + assert(lib); + assert(lib->isValid()); + + _library2OALib[library] = lib; + + for_each_library(l ,library->getLibraries()){ + getOALibForLibrary(l); + end_for; + } +/* + cerr << "Overwriting cds.lib file" << endl; + oaLibDefList *ldl = oaLibDefList::get( "cds.lib", 'a' ); + assert(ldl); + oaLibDef::create( ldl, scNameLib, strPathLib.c_str() ); + ldl->save(); + ldl->destroy(); + ldl = NULL; + cerr << "Overwrited cds.lib file" << endl; +*/ + + return lib; + } + + /** + convert oaLayer from a Layer ... + */ + oaLayer* getOALayerFromLayer(Layer* layer,oaTech* theOATech) { + assert(layer); + oaString layerName = getString(layer->getName()).c_str(); + oaPhysicalLayer* aOALayer = NULL; + BasicLayer* bLayer = dynamic_cast(layer); + if(bLayer) + aOALayer = oaPhysicalLayer::create(theOATech, layerName, _layerID++,getOAMaterial(bLayer->getMaterial())); + else + aOALayer = oaPhysicalLayer::create(theOATech, layerName, _layerID++); + assert(aOALayer); + + _layer2OAPhysicalLayer[layer] = aOALayer; + + //TODO: add oaConstraint and oaConstraintGroup defined by technology + DbU::Unit minSize = layer->getMinimalSize(); + oaLayerConstraint* cMinSize = oaLayerConstraint::create(aOALayer->getNumber(), + oaLayerConstraintDef::get(oacMinSize), + oaIntValue::create(aOALayer,minSize)); + DbU::Unit minSpace = layer->getMinimalSpacing(); + oaLayerConstraint* cMinSpace = oaLayerConstraint::create(aOALayer->getNumber(), + oaLayerConstraintDef::get(oacMinSpacing), + oaIntValue::create(aOALayer,minSpace)); + DbU::Unit pitch = layer->getPitch(); + oaLayerConstraint* cPitchH = oaLayerConstraint::create(aOALayer->getNumber(), + oaLayerConstraintDef::get(oacHorizontalRouteGridPitch), + oaIntValue::create(aOALayer,pitch)); + oaLayerConstraint* cPitchV = oaLayerConstraint::create(aOALayer->getNumber(), + oaLayerConstraintDef::get(oacVerticalRouteGridPitch), + oaIntValue::create(aOALayer,pitch)); + if(bLayer){ + unsigned gdsIInumber = bLayer->getExtractNumber(); + } + + return aOALayer; + } + + /** + print the oaLayera in a oaTech ... + */ + void printOALayers(oaTech* theOATech){ + assert(theOATech); oaIter lIter(theOATech->getLayers()); while(oaLayer* l = lIter.getNext()){ oaString layerName; l->getName(layerName); cerr << " o created oaLayer " << layerName << endl; } + } + + /** + 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) { + cerr << "createOATechForTechnology" << endl; + assert(technology); + if(_oaTech != NULL) + return _oaTech; + else + cerr << "working in createOATechForTechnology" << endl; + + //get or create Library for the techno + DataBase* db = technology->getDataBase(); + assert(db); + Library* lib = db->getRootLibrary(); + assert(lib); + oaLib* techOAlib = getOALibForLibrary(lib); + assert(techOAlib); + + cerr << "oaTech::find" << endl; + oaTech* theOATech = oaTech::find(techOAlib); + if(!theOATech){ + cerr << "oaTech::open" << endl; + theOATech = oaTech::open(techOAlib,'a'); + if(!theOATech){ + cerr << "oaTech::create" << endl; + theOATech = oaTech::create(techOAlib); + }else{ + _oaTech = theOATech; + return theOATech; + } + }else{ + _oaTech = theOATech; + return theOATech; + } + + assert(techOAlib); + theOATech->setDefaultManufacturingGrid(10); + theOATech->setDBUPerUU(oaViewType::get(oacMaskLayout), 1000); + + //TODO: add this layer + //first create "utility" layers + //strLayerDev ( "device" ); + //strLayerText( "text" ); + //strLayerPin ( "pin" ); + //strLayerCut1( "cut1" ); + //strLayerWire( "wire" ); + + //create physical layer + for_each_layer(layer, technology->getLayers()) { + getOALayerFromLayer(layer,theOATech); + end_for; + } + + printOALayers(theOATech); + + _oaTech = theOATech; return theOATech; } - oaDesign* getOADesignForCell(const Cell* cell) { - cerr << "getOADesignForCell " << cell << endl; - assert(cell); - Cell2OADesignMap::iterator it = _cell2OADesign4SchematicMap.find(cell); - if (it != _cell2OADesign4SchematicMap.end()) { - return it->second; - } - - oaNativeNS ns; - oaLib* lib = getOALibForLibrary(cell->getLibrary()); - assert(lib); - assert(_oaTech); - oaScalarName scNameDesign(ns, getString(cell->getName()).c_str()); - oaScalarName scNameViewSchematic(ns, "schematic"); - oaScalarName scNameViewLayout(ns, "layout"); - oaScalarName scNameLib; - lib->getName(scNameLib); - - // create a Schematic CellView of the design - oaDesign* schematicView = oaDesign::open(scNameLib, scNameDesign, scNameViewSchematic, oaViewType::get(oacSchematic), 'w'); - _cell2OADesign4SchematicMap[cell] = schematicView; - oaModule::create(schematicView); - oaBlock::create(schematicView); - // create a Layout CellView of the design - oaDesign* layoutView = oaDesign::open(scNameLib, scNameDesign, scNameViewLayout, oaViewType::get(oacMaskLayout), 'w'); - _cell2OADesign4LayoutMap[cell] = layoutView; - - //embed "module" domain in block domain - oaModule* topModule = oaModule::embed(layoutView,schematicView); - layoutView->setTopModule(topModule); - oaBlock* topBlock = layoutView->getTopBlock(); - assert(topBlock); - -/// fail because the AbutmentBox is empty -// oaBox box; -// getOABoxForBox(box, cell->getAbutmentBox()); -// cerr << cell << " " << cell->getAbutmentBox() << endl; -// oaRect::create(topBlock, 0, oaPurpose::get(_oaTech, oacDrawingPurposeType)->getNumber(), box); - - cerr << "transformation of instances" << endl; - for_each_instance(instance, cell->getInstances()) { + /** + 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); Cell* masterCell = instance->getMasterCell(); - oaDesign* masterDesign = getOADesignForCell(masterCell); + assert(masterCell); + oaDesign* masterDesign = createNetlist(masterCell); + assert(masterDesign); + + + oaNativeNS ns; oaScalarName scMasterName; masterDesign->getCellName(scMasterName); oaString strMasterName; @@ -396,72 +489,455 @@ namespace { oaTransform transform; getOATransformFromTransformation(transform, instance->getTransformation()); oaScalarInst* blockInst = oaScalarInst::create(topBlock, masterDesign, scInstName, transform); - _instance2OAInstMap[instance] = blockInst; - end_for; + _instance2OAInst[instance] = blockInst; + return blockInst; } - cerr << "transformation of nets" << endl; - for_each_net(net, cell->getNets()) { + + /** + 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::create(blockNet, scNetName, getOATermType(net->getDirection())); + assert(term); + oaPin* pin = oaPin::create(term); + assert(pin); + +/* oaLayerNum layer; + oaPurposeNum purpose; + getLayerPurpose(block->getDesign(), "pin", "drawing", layer, purpose); + oaPinFig *fig = oaPolygon::create(block, layer, purpose, points); +*/ + 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, + oaPurpose::get(_oaTech, oacDrawingPurposeType)->getNumber(), + box); + return rect; + } + + /** + convert Hurricane::Net to oaNet only at + the logical abstraction point of view + 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 = oaScalarNet::create(topBlock, scNetName, getOASigType(net->getType())); assert(blockNet); - oaOccNet* occNet = blockNet->getOccNet(); - assert(occNet); - assert(blockNet == occNet->getNet()); - oaModNet* moduleNet = occNet->getModNet(); - assert(moduleNet); if (net->isExternal()) { - oaTerm* term = oaTerm::create(blockNet, scNetName, getOATermType(net->getDirection())); - oaPin* pin = oaPin::create(term); + oaPin* pin = getOAPinFromNet(net,blockNet); Components externalComponents = NetExternalComponents::get(net); for_each_component(component, externalComponents) { - oaBox box; - getOABoxForBox(box, component->getBoundingBox()); - Layer* layer = (Layer*) component->getLayer(); - assert(layer); - oaPhysicalLayer* physLayer = NULL; - Layer2OAPhysicalLayerMap::iterator it = _layer2OAPhysicalLayerMap.find(layer); - if (it != _layer2OAPhysicalLayerMap.end()) { - physLayer = it->second; - } - assert(physLayer); - oaLayerNum layerNum = physLayer->getNumber(); - oaRect* rect = oaRect::create(topBlock, layerNum, - oaPurpose::get(_oaTech, oacDrawingPurposeType)->getNumber(), - box); + oaRect* rect = getOARectFromComponent(component,topBlock); rect->addToPin(pin); end_for; } } cerr << " o transformation of plugs" << endl; for_each_plug(plug, net->getPlugs()) { - Instance* instance = plug->getInstance(); - Instance2OAInstsMap::iterator it = _instance2OAInstMap.find(instance); - assert(it != _instance2OAInstMap.end()); - oaInst* blockInst = it->second; - oaInstTerm* instTerm = getInstTerm(blockInst, plug); - assert(instTerm); - instTerm->addToNet(blockNet); + getOAInstTermFromPlug(plug,blockNet); end_for; } - end_for; + return blockNet; } - return layoutView; - } -}; + + /** + create oaRect for slice ... + */ + oaRect* getOARectFromSlice(Slice* slice,oaBlock* topBlock){ + for_each_component(component, slice->getComponents()) { + oaRect* rect = getOARectFromComponent(component,topBlock); + end_for; + } + } + + /** + Create oaDesign for netlist Cell View from the cell + */ + oaDesign* createNetlist(const Cell* cell) { + cerr << "createNetlist " << cell << endl; + assert(cell); + Cell2OADesignMap::iterator it = _cell2OADesign4Netlist.find(cell); + if (it != _cell2OADesign4Netlist.end()) { + return it->second; + } + + getOATechForTechnology(_technology); + oaNativeNS ns; + oaLib* lib = getOALibForLibrary(cell->getLibrary()); + assert(lib); + oaScalarName scNameDesign(ns, getString(cell->getName()).c_str()); + oaScalarName scNameView(ns, "netlist"); + oaScalarName scNameLib; + lib->getName(scNameLib); + + // create a netlist CellView of the cell + cerr << "oaDesign::open for netlist view" << endl; + oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, oaViewType::get(oacNetlist), 'w'); + _cell2OADesign4Netlist[cell] = designCellView; + cerr << "oaBlock::create for netlist view" << endl; + oaBlock* topBlock = oaBlock::create(designCellView); + assert(topBlock); + + cerr << "transformation of slices" << endl; + for_each_slice(slice, cell->getSlices()){ + getOARectFromSlice(slice,topBlock); + end_for; + } + 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; + } + + 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; + } + + getOATechForTechnology(_technology); + 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 + cerr << "oaDesign::open for schematic view" << endl; + oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, oaViewType::get(oacSchematic), 'w'); + _cell2OADesign4Schematic[cell] = designCellView; + + return designCellView; + } + + 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; + } + + getOATechForTechnology(_technology); + 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 + cerr << "oaDesign::open for symbolic view" << endl; + oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, oaViewType::get(oacSchematicSymbol), 'w'); + _cell2OADesign4Symbolic[cell] = designCellView; + + return designCellView; + } + + + /** + from genPhysical in OAGear + */ + double findArea(oaBlock *block) { + double totalArea = 0.0; + oaIter instIter(block->getInsts()); + while (oaInst *i = instIter.getNext()) { + oaDesign *master = i->getMaster(); + if (!master) { + oaString nameString; + i->getName(oaNativeNS(), nameString); + std::cerr << "Warning: black box found, assuming zero area:" + << nameString << std::endl; + } else { + oaBlock *masterBlock = master->getTopBlock(); + assert(masterBlock); + oaPRBoundary *bound = oaPRBoundary::find(masterBlock); + assert(bound); + oaBox bbox; + bound->getBBox(bbox); + oaUInt8 cellArea = static_cast(bbox.getWidth()) * + static_cast(bbox.getHeight()); + oaTech *tech = master->getTech(); + assert(tech); + totalArea += tech->dbuToUUArea(oaViewType::get(oacMaskLayout), cellArea); + } + } + return totalArea; + } + + /** + from genPhysical in OAGear + */ + oaSiteDef * findSiteDef(oaTech *tech){ + oaSiteDef *r = 0; + oaIter siteIter(tech->getSiteDefs()); + while (oaSiteDef *i = siteIter.getNext()) { + if (i->getSiteDefType() == oacCoreSiteDefType) { + if (!r || r->getWidth() > i->getWidth()) { + r = i; + } + } + } + return r; + } + + /** + from genPhysical in OAGear + */ + oaLayer * findMetal3(oaTech *tech){ + oaIter oaLayerIter(tech->getLayers()); + while (oaLayer *i = oaLayerIter.getNext()) { + if (i->getType() != oacPhysicalLayerType) { + continue; + } + oaMaterial m = (static_cast(i))->getMaterial(); + if (m != oacMetalMaterial) { + continue; + } + int metalLayersBelow = 0; + oaPhysicalLayer *belowLayer = (static_cast(i)) + ->getLayerBelow(oacMetalMaterial); + while (belowLayer) { + metalLayersBelow++; + belowLayer = + belowLayer->getLayerBelow(oacMetalMaterial); + } + if (metalLayersBelow == 2) { + return i; + } + } + return 0; + } + + /** + from genPhysical main in OAGear + */ + void genPhysical(oaDesign* physCV,oaDesign* netlistCV){ + double utilization = 0.70; + + // merge logically equivalent nets in original netlist view + oaBlock *topNetlistBlock = netlistCV->getTopBlock(); + assert(topNetlistBlock); + oaIter netIter(topNetlistBlock->getNets( + oacNetIterSingleBit | oacNetIterNotImplicit)); + while (oaNet *n = netIter.getNext()) { + oaBitNet *bn = static_cast(n); + oaBitNet *en = bn->getPreferredEquivalent(); + if (en != bn) { + en->merge(bn); + } + } + + // embed netlist into physical view + oaModule *topMod = oaModule::embed(physCV, netlistCV); + physCV->setTopModule(topMod); + oaBlock *topBlock = physCV->getTopBlock(); + assert(topBlock); + double totalArea = findArea(topBlock); + if (totalArea == 0.0) { + std::cerr << "ERROR : Design has zero area" << std::endl; + return ; + } + unsigned int numTerms = topBlock->getTerms().getCount(); + if (!numTerms) { + std::cerr << "ERROR : Design has no terms" << std::endl; + return ; + } + oaSiteDef *mySiteDef = findSiteDef(_oaTech); + assert(mySiteDef); + // compute die width and height + double width = sqrt(totalArea / utilization); + oaInt4 dbWidth = _oaTech->uuToDBUDistance(oaViewType::get(oacMaskLayout), width); + oaInt4 numSites = dbWidth / mySiteDef->getWidth() + 1; + dbWidth = numSites * mySiteDef->getWidth(); + double height = sqrt(totalArea / utilization); + oaInt4 dbHeight = _oaTech->uuToDBUDistance(oaViewType::get(oacMaskLayout), height); + oaInt4 numRows = dbHeight / mySiteDef->getHeight() + 1; + dbHeight = numRows * mySiteDef->getHeight(); + oaConstraintGroup *cg = oaConstraintGroup::find(_oaTech, "LEFDefaultRouteSpec"); + assert(cg); + // generate pins for terms and assign to boundary + double jump = (static_cast(dbWidth) + dbHeight) + * 2.0 / numTerms; + jump = static_cast(jump / mySiteDef->getWidth()); + assert(jump >= 1.0); + jump *= mySiteDef->getWidth(); + double pos = 0.0; + std::vector posVector(numTerms); + for (unsigned int i = 0; i < numTerms; ++i) { + posVector[i] = pos; + pos += jump; + } + std::random_shuffle(posVector.begin(), posVector.end()); + // find the route layer - Metal3 + oaLayer *routeLayer = findMetal3(_oaTech); + assert(routeLayer); + oaLayerNum routeLayerNum(routeLayer->getNumber()); + // get route width constraint for metal 3 to compute size of pins + oaConstraint *cons = oaLayerConstraint::find(cg, routeLayerNum, + oaLayerConstraintDef::get(oacMinWidth)); + oaValue *val = cons->getValue(); + oaInt4 m3Width = static_cast(val)->get(); + oaIter termIter(topBlock->getTerms()); + while (oaTerm *i = termIter.getNext()) { + pos = posVector.back(); + double x, y; + if (pos < dbWidth) { + x = pos; + y = 0.0; + } else if (pos < dbWidth + dbHeight) { + x = dbWidth; + y = pos - dbWidth; + } else if (pos < 2.0 * dbWidth + dbHeight) { + x = 2.0 * dbWidth + dbHeight - pos; + y = dbHeight; + } else { + x = 0.0; + y = 2.0 * dbWidth + 2.0 * dbHeight - pos; + } + oaInt4 ux = static_cast(x); + oaInt4 uy = static_cast(y); + oaBox pinBox(ux - m3Width / 2, uy - m3Width / 2, + ux + m3Width / 2, uy + m3Width / 2); + oaRect *pinRect = oaRect::create(topBlock, routeLayerNum, + oavPurposeNumberDrawing, pinBox); + assert(pinRect); + oaPin *pin = oaPin::create(i); + assert(pin); + pinRect->addToPin(pin); + pin->setPlacementStatus(oacFixedPlacementStatus); + posVector.pop_back(); + } + oaPointArray prBoundPoints(4); + oaPoint p0(0, 0); + prBoundPoints.append(p0); + oaPoint p1(0, dbHeight); + prBoundPoints.append(p1); + oaPoint p2(dbWidth, dbHeight); + prBoundPoints.append(p2); + oaPoint p3(dbWidth, 0); + prBoundPoints.append(p3); + oaPRBoundary *boundary = oaPRBoundary::create(topBlock, prBoundPoints); + oaBox cBox(p0, p2); + oaCoreBoxSpec coreSpec(cBox); + } + + 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; + } + + getOATechForTechnology(_technology); + 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 + cerr << "oaDesign::open for layout view" << endl; + oaDesign* designCellView = oaDesign::open(scNameLib, scNameDesign, scNameView, oaViewType::get(oacMaskLayout), 'w'); + _cell2OADesign4Layout[cell] = designCellView; + + +// genPhysical(designCellView,previous); + + return designCellView; + } + + oaDesign* getOADesignForCell(const Cell* cell) { + cerr << "getOADesignForCell " << cell << endl; + assert(cell); + + oaDesign* netlistView = createNetlist(cell); + assert(netlistView); + + oaDesign* symbolicView = addSymbol(cell,netlistView); + assert(symbolicView); + + oaDesign* schematicView = addSchematic(cell,netlistView); + assert(schematicView); + + oaDesign* layoutView = addLayout(cell,schematicView); + assert(layoutView); + + return layoutView; + } + }; #endif } + namespace CRL { void OpenAccessWrapper::oaDriver(const string& path, Cell* cell) { #ifdef HAVE_OPENACCESS //for the moment a driver for hurricaneAMS - //save the Cell and all used Cells + //save the Cell only and all used Cells cerr << "Saving " << cell << " in " << path << endl; try { - oaDesignInit(); -// oaDesignInit(oacAPIMajorRevNumber, -// oacAPIMinorRevNumber, -// oacDataModelRevNumber); + oaDesignInit(oacAPIMajorRevNumber, + oacAPIMinorRevNumber, + oacDataModelRevNumber); OADriver oaDriver(path); oaDesign* design = oaDriver.getOADesignForCell(cell); diff --git a/crlcore/src/ccore/openaccess/test/CMakeLists.txt b/crlcore/src/ccore/openaccess/test/CMakeLists.txt index b22393cf..fa8d564f 100755 --- a/crlcore/src/ccore/openaccess/test/CMakeLists.txt +++ b/crlcore/src/ccore/openaccess/test/CMakeLists.txt @@ -2,12 +2,19 @@ PROJECT(testOAWrapper) CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0) -SET(CMAKE_MODULE_PATH "$ENV{CORIOLIS_USER_TOP}/share/cmake/Modules/" - "$ENV{CORIOLIS_TOP}/share/cmake/Modules/" - "$ENV{IO_USER_TOP}/share/cmake/Modules/" - "$ENV{IO_TOP}/share/cmake/Modules/" - "$ENV{CHAMS_USER_TOP}/share/cmake/Modules/" - "$ENV{CHAMS_TOP}/share/cmake/Modules/") +LIST(INSERT CMAKE_MODULE_PATH 0 "$ENV{BOOTSTRAP_TOP}/share/cmake/Modules/") +find_package(Bootstrap REQUIRED) +setup_project_paths(VLSISAPD) +setup_project_paths(CORIOLIS) + +LIST(INSERT CMAKE_MODULE_PATH 0 "${CRLCORE_SOURCE_DIR}/cmake_modules/") + + +LIST(INSERT CMAKE_MODULE_PATH 0 "${CRLCORE_SOURCE_DIR}/cmake_modules/") +LIST(INSERT CMAKE_MODULE_PATH 0 + "$ENV{CHAMS_USER_TOP}/share/cmake/Modules/" + "$ENV{CHAMS_TOP}/share/cmake/Modules/") +print_cmake_module_path() FIND_PACKAGE(HURRICANE REQUIRED) FIND_PACKAGE(CORIOLIS REQUIRED) diff --git a/crlcore/src/ccore/openaccess/test/src/main.cpp b/crlcore/src/ccore/openaccess/test/src/main.cpp index 55463877..d471558d 100755 --- a/crlcore/src/ccore/openaccess/test/src/main.cpp +++ b/crlcore/src/ccore/openaccess/test/src/main.cpp @@ -8,6 +8,7 @@ // x-----------------------------------------------------------------x #include +#include using namespace std; @@ -19,6 +20,7 @@ using namespace Hurricane; #include "crlcore/Catalog.h" #include "crlcore/RealTechnologyParser.h" +#include "crlcore/SymbolicTechnologyParser.h" #include "crlcore/AllianceFramework.h" #include "hurricaneAMS/environment/AnalogEnv.h" @@ -33,9 +35,12 @@ namespace { }; void testCell(Cell* dev){ - if(dev) + if(dev){ cout << "Cell created" << endl; - + }else{ + cout << "Cell not created" << endl; + return; + } // cout << "driving GDS" << endl; // CRL::GdsDriver(dev).save("/tmp/testGDS"); @@ -72,28 +77,22 @@ void testAnalog(char* pathToConf){ TransistorFamily::NMOS, bulkConnected); - cout << "testing cell myCM" << endl; - + cout << "testing cell myCM" << endl; testCell(dev); db->destroy(); } void testNum(){ cout << "creating cell from sxlib inv_x1" << endl; - CRL::AllianceFramework::get(); - DataBase* db = DataBase::getDB(); - assert(db != NULL); - CRL::RealTechnologyParser::load(db, "/asim/coriolis2/etc/coriolis2/technology.freePDK45.s2r.xml"); + DataBase* db = NULL; Cell* mySxlibCell = CRL::AllianceFramework::get()->getCell( "inv_x1", CRL::Catalog::State::Views ); cout << "testing cell from sxlib inv_x1" << endl; testCell(mySxlibCell); db = DataBase::getDB(); assert(db != NULL); - db->destroy(); + db->destroy(); } - - int main(int argc,char** argv) { if(argc != 2) exit(-5);