From f537a10d45b74f45e608665fea432306ff884fbc Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 7 Jan 2016 13:13:16 +0100 Subject: [PATCH] Implementation of DataBase native save/restore in JSON (step 1). * New: In Hurricane, added first support for DataBase native import/export using JSON. We choose RapidJSON, in SAX mode, to manage the JSON format low level Read/Write. Thus, it's Git repository http://github.com/miloyip/rapidjson must be added under ~/coriolis-2.x/src and manually build and installed in the Coriolis installation tree (to be integrated in ccb later). Two mode are being supported: 1. Cell mode: one Cell only is saved. In that mode, Entities referred by Occurrences are "outside" the file. They are coded through their "signature" (mostly, all the values of their attributes). The ids saved in the file cannot be restored identically as we cannot predict when and in which context the Cell will be reloaded. 2. Design Blob mode: the whole design hierarchy, down and including the standard cells is saved. This way the design is completly self contained and Entities ared referred through their ids. A design blob can only be loaded immediatly after starting cgt as the DataBase *must* be empty. This way we restore the whole design hierarchy with *exactly* the same ids. Now, Hurricane object should provide a "toJson()" method for driving JSON, and be associated with a JsonObject derived class for parsing. * New: In Hurricane, ability to force the next id that will be used for a DBo (used by Design Blob Mode). * New: In Hurricane, in DataBase, added getCell() and getLibrary() functions to allow the hierarchical access of a Cell/Library in native mode (i.e. whithout the requirement of AllianceFramework). * New: In Hurricane, In CellViewer, added menu entry for Save/Load of JSON Design Blobs. Added at this level because we consider it as the "native" format of Hurricane. * New: In Unicorn, added support of import/export of JSON Cell. * Bug: In Hurricane, in Instance, when cloning an Instance or uniquifying it's master Cell, we forgot about the Occurrences (through shared pathes). When an instance is cloned the Shared pathes still points toward the original Instance. And when it's the master Cell that is uniquifyed it's the Entities pointed to that remains in the original Cell. This is a software design problem. It is difficult to define what policy to adopt when uniquifying: basically that means that one Occurence is either moved onto the clone or duplicated. Furthermore, it is not trivial to known what Occurrence is pointing on the uniquifyed/cloned item. Have to think about it a little more. * Bug: In Etesian, in EtesianEngine, build the flattened nets and their RoutingPads *after* uniquifying (through slaving bounding boxes). This way we avoid the Occurrences problem described above. * Bug: In Etesian, in EtesianEngine, invalidate the RoutingPad after processing the placement so they are put into the right quadtree. This problem is due to the fact that the RoutingPads do not belong to the Instance that they refer. And when this instance is moved around, she doesn't inform the RoutingPad that is has moved. More software architecture design to review... --- crlcore/src/ccore/AllianceFramework.cpp | 50 +- crlcore/src/ccore/crlcore/AllianceFramework.h | 1 + etesian/src/EtesianEngine.cpp | 18 +- hurricane/src/hurricane/Box.cpp | 54 +- hurricane/src/hurricane/CMakeLists.txt | 9 + hurricane/src/hurricane/Cell.cpp | 145 +++ hurricane/src/hurricane/Component.cpp | 54 +- hurricane/src/hurricane/Contact.cpp | 81 +- hurricane/src/hurricane/DBo.cpp | 51 +- hurricane/src/hurricane/DataBase.cpp | 51 +- hurricane/src/hurricane/DeepNet.cpp | 58 +- hurricane/src/hurricane/DesignBlob.cpp | 74 ++ hurricane/src/hurricane/Entity.cpp | 112 +- hurricane/src/hurricane/Hook.cpp | 26 + hurricane/src/hurricane/Horizontal.cpp | 57 + hurricane/src/hurricane/Instance.cpp | 98 +- hurricane/src/hurricane/JsonReader.cpp | 821 ++++++++++++ hurricane/src/hurricane/JsonWriter.cpp | 101 ++ hurricane/src/hurricane/Layer.cpp | 7 +- hurricane/src/hurricane/Library.cpp | 77 ++ hurricane/src/hurricane/Net.cpp | 133 +- hurricane/src/hurricane/Occurrence.cpp | 88 ++ hurricane/src/hurricane/Pad.cpp | 50 + hurricane/src/hurricane/Path.cpp | 20 +- hurricane/src/hurricane/Plug.cpp | 122 +- hurricane/src/hurricane/Point.cpp | 33 + hurricane/src/hurricane/RoutingPad.cpp | 70 +- hurricane/src/hurricane/Segment.cpp | 66 +- hurricane/src/hurricane/SharedPath.cpp | 17 + hurricane/src/hurricane/Signature.cpp | 167 +++ hurricane/src/hurricane/Tabulation.cpp | 3 +- hurricane/src/hurricane/Transformation.cpp | 56 + hurricane/src/hurricane/Vertical.cpp | 57 + hurricane/src/hurricane/grenier/json/DBo.cpp | 198 +++ hurricane/src/hurricane/grenier/json/DBo.h | 114 ++ .../src/hurricane/grenier/json/JsonReader.cpp | 650 ++++++++++ .../src/hurricane/grenier/json/JsonReader.h | 790 ++++++++++++ hurricane/src/hurricane/grenier/json/Net.cpp | 1106 +++++++++++++++++ hurricane/src/hurricane/grenier/json/Net.h | 363 ++++++ hurricane/src/hurricane/hurricane/Box.h | 13 +- hurricane/src/hurricane/hurricane/Cell.h | 16 +- .../src/hurricane/hurricane/Collection.h | 191 ++- hurricane/src/hurricane/hurricane/Commons.h | 2 + hurricane/src/hurricane/hurricane/Component.h | 13 +- hurricane/src/hurricane/hurricane/Contact.h | 14 +- hurricane/src/hurricane/hurricane/DBo.h | 93 +- hurricane/src/hurricane/hurricane/DataBase.h | 10 +- hurricane/src/hurricane/hurricane/DbU.h | 4 + hurricane/src/hurricane/hurricane/DeepNet.h | 64 +- .../src/hurricane/hurricane/DesignBlob.h | 60 + hurricane/src/hurricane/hurricane/Entity.h | 56 +- hurricane/src/hurricane/hurricane/Hook.h | 8 +- .../src/hurricane/hurricane/Horizontal.h | 11 + hurricane/src/hurricane/hurricane/Instance.h | 17 + hurricane/src/hurricane/hurricane/Interval.h | 9 + .../src/hurricane/hurricane/IntrusiveMap.h | 16 + .../src/hurricane/hurricane/IntrusiveSet.h | 5 + .../src/hurricane/hurricane/JsonReader.h | 439 +++++++ .../src/hurricane/hurricane/JsonWriter.h | 207 +++ hurricane/src/hurricane/hurricane/Layer.h | 1 + hurricane/src/hurricane/hurricane/Library.h | 12 + hurricane/src/hurricane/hurricane/Name.h | 6 + hurricane/src/hurricane/hurricane/Net.h | 23 +- hurricane/src/hurricane/hurricane/NetAlias.h | 3 + .../src/hurricane/hurricane/Occurrence.h | 17 +- hurricane/src/hurricane/hurricane/Pad.h | 11 + hurricane/src/hurricane/hurricane/Path.h | 1 + hurricane/src/hurricane/hurricane/Plug.h | 20 + hurricane/src/hurricane/hurricane/Point.h | 12 +- .../src/hurricane/hurricane/RoutingPad.h | 22 +- hurricane/src/hurricane/hurricane/Segment.h | 19 +- .../src/hurricane/hurricane/SharedPath.h | 1 + hurricane/src/hurricane/hurricane/Signature.h | 149 +++ .../src/hurricane/hurricane/Tabulation.h | 2 +- .../src/hurricane/hurricane/Transformation.h | 12 +- hurricane/src/hurricane/hurricane/Vertical.h | 11 + hurricane/src/isobar/CMakeLists.txt | 1 + hurricane/src/viewer/CMakeLists.txt | 2 + hurricane/src/viewer/CellPrinter.cpp | 4 +- hurricane/src/viewer/CellViewer.cpp | 50 + hurricane/src/viewer/CellWidget.cpp | 2 +- hurricane/src/viewer/OpenBlobDialog.cpp | 97 ++ .../src/viewer/hurricane/viewer/CellViewer.h | 2 + .../viewer/hurricane/viewer/OpenBlobDialog.h | 42 + unicorn/src/ExportCellDialog.cpp | 1 + unicorn/src/UnicornGui.cpp | 16 +- unicorn/src/unicorn/ExportCellDialog.h | 2 +- 87 files changed, 7620 insertions(+), 217 deletions(-) create mode 100644 hurricane/src/hurricane/DesignBlob.cpp create mode 100644 hurricane/src/hurricane/JsonReader.cpp create mode 100644 hurricane/src/hurricane/JsonWriter.cpp create mode 100644 hurricane/src/hurricane/Signature.cpp create mode 100644 hurricane/src/hurricane/grenier/json/DBo.cpp create mode 100644 hurricane/src/hurricane/grenier/json/DBo.h create mode 100644 hurricane/src/hurricane/grenier/json/JsonReader.cpp create mode 100644 hurricane/src/hurricane/grenier/json/JsonReader.h create mode 100644 hurricane/src/hurricane/grenier/json/Net.cpp create mode 100644 hurricane/src/hurricane/grenier/json/Net.h create mode 100644 hurricane/src/hurricane/hurricane/DesignBlob.h create mode 100644 hurricane/src/hurricane/hurricane/JsonReader.h create mode 100644 hurricane/src/hurricane/hurricane/JsonWriter.h create mode 100644 hurricane/src/hurricane/hurricane/Signature.h create mode 100644 hurricane/src/viewer/OpenBlobDialog.cpp create mode 100644 hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index 847517f6..01b83216 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -13,32 +13,28 @@ // | C++ Module : "./AllianceFramework.cpp" | // +-----------------------------------------------------------------+ - -#include -#include "vlsisapd/utilities/Path.h" -#include "hurricane/Warning.h" -#include "hurricane/Technology.h" -#include "hurricane/DataBase.h" -#include "hurricane/Library.h" -#include "hurricane/Cell.h" -#include "hurricane/Instance.h" -#include "hurricane/viewer/Graphics.h" -#include "crlcore/Utilities.h" -#include "crlcore/GraphicsParser.h" -#include "crlcore/SymbolicTechnologyParser.h" -#include "crlcore/RealTechnologyParser.h" -#include "crlcore/CellGauge.h" -#include "crlcore/RoutingGauge.h" -#include "crlcore/RoutingLayerGauge.h" -#include "crlcore/AllianceFramework.h" - - - +#include +#include "vlsisapd/utilities/Path.h" +#include "hurricane/Warning.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/viewer/Graphics.h" +#include "crlcore/Utilities.h" +#include "crlcore/GraphicsParser.h" +#include "crlcore/SymbolicTechnologyParser.h" +#include "crlcore/RealTechnologyParser.h" +#include "crlcore/CellGauge.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/AllianceFramework.h" namespace CRL { - + using namespace std::placeholders; using Hurricane::Warning; using Hurricane::tab; using Hurricane::Graphics; @@ -133,6 +129,7 @@ namespace CRL { db = DataBase::create (); db->put ( AllianceFrameworkProperty::create(this) ); + db->_setCellLoader( bind(&AllianceFramework::cellLoader,this,_1) ); //cmess1 << " o Reading Alliance Environment." << endl; @@ -262,6 +259,15 @@ namespace CRL { } + Cell* AllianceFramework::cellLoader ( const string& rpath ) + { + size_t dot = rpath.rfind('.'); + string cellName = rpath.substr(dot+1); + + return getCell( cellName, Catalog::State::Views ); + } + + Cell* AllianceFramework::getCell ( const string& name, unsigned int mode, unsigned int depth ) { bool createCell = false; diff --git a/crlcore/src/ccore/crlcore/AllianceFramework.h b/crlcore/src/ccore/crlcore/AllianceFramework.h index 53acb7fa..e41b43f1 100644 --- a/crlcore/src/ccore/crlcore/AllianceFramework.h +++ b/crlcore/src/ccore/crlcore/AllianceFramework.h @@ -85,6 +85,7 @@ namespace CRL { void addRoutingGauge ( RoutingGauge* ); void addCellGauge ( CellGauge* ); // Cell Management. + Cell* cellLoader ( const string& rpath ); Cell* getCell ( const string& name , unsigned int mode , unsigned int depth=(unsigned int)-1 ); diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index a76f207d..d59eacbb 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -453,10 +453,6 @@ namespace Etesian { if (not cmess2.enabled()) dots.disable(); - cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; - //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); - getCell()->flattenNets( Cell::Flags::NoClockFlatten ); - // Coloquinte circuit description data-structures. size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize(); vector idsToTransf ( instancesNb ); @@ -487,6 +483,10 @@ namespace Etesian { } UpdateSession::close(); + cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; + //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); + getCell()->flattenNets( Cell::Flags::NoClockFlatten ); + index_t instanceId = 0; for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) { @@ -925,6 +925,14 @@ namespace Etesian { _placed = true; + UpdateSession::open(); + for ( Net* net : getCell()->getNets() ) { + for ( RoutingPad* rp : net->getComponents().getSubSet() ) { + rp->invalidate(); + } + } + UpdateSession::close(); + getCell()->setFlags( Cell::Flags::Placed ); } @@ -999,7 +1007,7 @@ namespace Etesian { ); //cerr << "Setting <" << instanceName << " @" << instancePosition << endl; - // This is temporary as it's not trans-hierarchic: we ignore the posutions + // This is temporary as it's not trans-hierarchic: we ignore the positions // of all the intermediary instances. instance->setTransformation( trans ); instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); diff --git a/hurricane/src/hurricane/Box.cpp b/hurricane/src/hurricane/Box.cpp index 5cb0e291..bad9ce79 100644 --- a/hurricane/src/hurricane/Box.cpp +++ b/hurricane/src/hurricane/Box.cpp @@ -318,7 +318,7 @@ Box& Box::merge(const Box& box) } Box& Box::translate(const DbU::Unit& dx, const DbU::Unit& dy) -// ************************************************ +// ********************************************************** { if (!isEmpty()) { _xMin += dx; @@ -353,6 +353,58 @@ Record* Box::_getRecord() const return record; } +void Box::toJson(JsonWriter* w) const +// *********************************** +{ + w->startObject(); + jsonWrite( w, "@typename", "Box" ); + jsonWrite( w, "_xMin", getXMin() ); + jsonWrite( w, "_yMin", getYMin() ); + jsonWrite( w, "_xMax", getXMax() ); + jsonWrite( w, "_yMax", getYMax() ); + w->endObject(); +} + +JsonBox::JsonBox(unsigned long flags) +// ********************************** + : JsonObject(flags) +{ + add( "_xMin", typeid(int64_t) ); + add( "_yMin", typeid(int64_t) ); + add( "_xMax", typeid(int64_t) ); + add( "_yMax", typeid(int64_t) ); +} + +string JsonBox::getTypeName() const +// ********************************* +{ return "Box"; } + +JsonBox* JsonBox::clone(unsigned long flags) const +// *********************************************** +{ return new JsonBox ( flags ); } + +void JsonBox::toData(JsonStack& stack) +// *********************************** +{ + check( stack, "JsonBox::toData" ); + + DbU::Unit xMin = DbU::fromDb(get(stack,"_xMin")); + DbU::Unit yMin = DbU::fromDb(get(stack,"_yMin")); + DbU::Unit xMax = DbU::fromDb(get(stack,"_xMax")); + DbU::Unit yMax = DbU::fromDb(get(stack,"_yMax")); + + Box box; + + if ( (xMin <= xMax) and (yMin <= yMax) ) + box.merge( xMin, yMin, xMax, yMax ); + + ltrace(51) << "Box(" << xMin << ", " + << yMin << ", " + << xMax << ", " + << yMax << ")" << endl; + + update( stack, box ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index abb9a7c2..55b6b7bc 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -1,11 +1,15 @@ include_directories ( ${HURRICANE_SOURCE_DIR}/src/hurricane + ${CONFIGURATION_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) set ( includes hurricane/Mask.h hurricane/Flags.h hurricane/DebugSession.h hurricane/Backtrace.h + hurricane/JsonWriter.h + hurricane/JsonReader.h + hurricane/Signature.h hurricane/Observer.h hurricane/BasicLayer.h hurricane/BasicLayers.h hurricane/RegularLayer.h hurricane/RegularLayers.h @@ -90,12 +94,16 @@ hurricane/Views.h hurricane/Warning.h hurricane/TextTranslator.h + hurricane/DesignBlob.h ) set ( cpps Record.cpp Slot.cpp Commons.cpp Flags.cpp Backtrace.cpp + JsonWriter.cpp + JsonReader.cpp + Signature.cpp Exception.cpp Bug.cpp Error.cpp @@ -164,6 +172,7 @@ Marker.cpp Timer.cpp TextTranslator.cpp + DesignBlob.cpp ) add_library ( hurricane ${cpps} ) diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 81bb29b4..dbabfe17 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -28,6 +28,10 @@ #include "hurricane/Net.h" #include "hurricane/Pin.h" #include "hurricane/RoutingPad.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Contact.h" +#include "hurricane/Pad.h" #include "hurricane/Layer.h" #include "hurricane/Slice.h" #include "hurricane/Rubber.h" @@ -254,6 +258,91 @@ bool Cell::isUniquifyMaster() const return (not relation) or (relation->getMasterOwner() == this); } +string Cell::getHierarchicalName () const +// ************************************** +{ + return getLibrary()->getHierarchicalName() + "." + getString(getName()); +} + +Entity* Cell::getEntity(const Signature& signature) const +// ****************************************************** +{ + if ( (signature.getType() == Signature::TypeContact ) + or (signature.getType() == Signature::TypeHorizontal) + or (signature.getType() == Signature::TypeVertical ) + or (signature.getType() == Signature::TypePad ) ) { + Net* net = getNet( signature.getName() ); + if (not net) { + cerr << Error( "Cell::getEntity(): Cell %s do have Net %s, signature incoherency." + , getString(getName()).c_str() + , signature.getName().c_str() ) << endl; + return NULL; + } + + ltrace(51) << "Cell::getEntity(): <" << getName() << ">, Net:<" << net->getName() << ">" << endl; + + if (signature.getType() == Signature::TypeContact) { + ltrace(51) << "Looking in Contacts..." << endl; + for ( Contact* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer () == signature.getLayer()) + and (component->getDx () == signature.getDim(Signature::ContactDx)) + and (component->getDy () == signature.getDim(Signature::ContactDy)) + and (component->getWidth () == signature.getDim(Signature::ContactWidth)) + and (component->getHeight() == signature.getDim(Signature::ContactHeight)) ) + return component; + } + } + + if (signature.getType() == Signature::TypeVertical) { + ltrace(51) << "Looking in Verticals..." << endl; + for ( Vertical* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer () == signature.getLayer()) + and (component->getWidth () == signature.getDim(Signature::VerticalWidth)) + and (component->getX () == signature.getDim(Signature::VerticalX)) + and (component->getDySource() == signature.getDim(Signature::VerticalDySource)) + and (component->getDyTarget() == signature.getDim(Signature::VerticalDyTarget)) ) + return component; + } + } + + if (signature.getType() == Signature::TypeHorizontal) { + ltrace(51) << "Looking in Horizontals..." << endl; + for ( Horizontal* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer () == signature.getLayer()) + and (component->getWidth () == signature.getDim(Signature::HorizontalWidth)) + and (component->getY () == signature.getDim(Signature::HorizontalY)) + and (component->getDxSource() == signature.getDim(Signature::HorizontalDxSource)) + and (component->getDxTarget() == signature.getDim(Signature::HorizontalDxTarget)) ) + return component; + } + } + + if (signature.getType() == Signature::TypePad) { + ltrace(51) << "Looking in Pads..." << endl; + for ( Pad* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer() == signature.getLayer()) + and (component->getBoundingBox().getXMin() == signature.getDim(Signature::PadXMin)) + and (component->getBoundingBox().getYMin() == signature.getDim(Signature::PadYMin)) + and (component->getBoundingBox().getXMax() == signature.getDim(Signature::PadXMax)) + and (component->getBoundingBox().getYMax() == signature.getDim(Signature::PadYMax)) ) + return component; + } + } + + cerr << Error( "Cell::getEntity(): Cannot find a Component of type %d matching Signature." + , signature.getType() ) << endl; + } else { + cerr << Error( "Cell::getEntity(): Signature type %d is unsupported yet." + , signature.getType() ) << endl; + } + + return NULL; +} + Net* Cell::getNet ( const Name& name ) const //****************************************** { @@ -793,6 +882,23 @@ void Cell::notify(unsigned flags) _observers.notify(flags); } +void Cell::_toJson(JsonWriter* writer) const +// ***************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_library" , getLibrary()->getHierarchicalName() ); + jsonWrite( writer, "_name" , getName() ); + jsonWrite( writer, "_abutmentBox", &_abutmentBox ); +} + +void Cell::_toJsonCollections(JsonWriter* writer) const +// ***************************************** +{ + jsonWrite( writer, "+instanceMap", getInstances() ); + jsonWrite( writer, "+netMap" , getNets() ); + Inherit::_toJsonCollections( writer ); +} // **************************************************************************************************** // Cell::Flags implementation @@ -1105,6 +1211,45 @@ void Cell::MarkerSet::_setNextElement(Marker* marker, Marker* nextMarker) const marker->_setNextOfCellMarkerSet(nextMarker); } + + +// **************************************************************************************************** +// JsonCell implementation +// **************************************************************************************************** + +JsonCell::JsonCell(unsigned long flags) +// ************************************ + : JsonEntity(flags) +{ + remove( ".Cell" ); + add( "_library" , typeid(string) ); + add( "_name" , typeid(string) ); + add( "_abutmentBox" , typeid(Box) ); + add( "+instanceMap" , typeid(JsonArray) ); + add( "+netMap" , typeid(JsonArray) ); +} + +string JsonCell::getTypeName() const +// ********************************* +{ return "Cell"; } + +JsonCell* JsonCell::clone(unsigned long flags) const +// ************************************************* +{ return new JsonCell ( flags ); } + +void JsonCell::toData(JsonStack& stack) +// ************************************ +{ + check( stack, "JsonCell::toData" ); + presetId( stack ); + + Cell* cell = Cell::create( DataBase::getDB()->getLibrary( get(stack,"_library") ) + , get(stack,"_name") ); + cell->setAbutmentBox( stack.as("_abutmentBox") ); + + update( stack, cell ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Component.cpp b/hurricane/src/hurricane/Component.cpp index 70f7463a..4405a6df 100644 --- a/hurricane/src/hurricane/Component.cpp +++ b/hurricane/src/hurricane/Component.cpp @@ -378,6 +378,25 @@ void Component::invalidate(bool propagateFlag) } } + +void Component::forceId(unsigned int id) +// ************************************* +{ + if (not inForcedIdMode()) + throw Error( "Component::forceId(): DataBase *must* be in forced id mode to call this method." ); + + if (getId() == id) return; + + bool materialized = isMaterialized(); + if (materialized) unmaterialize(); + if (_net) _net->_getComponentSet()._remove(this); + + setId( id ); + + if (_net) _net->_getComponentSet()._insert(this); + if (materialized) materialize(); +} + void Component::_postCreate() // ************************** { @@ -454,6 +473,20 @@ void Component::_preDestroy() // trace_out(); } +void Component::_toJson( JsonWriter* writer ) const +// ************************************************ +{ + Inherit::_toJson( writer ); + jsonWrite( writer, "_bodyHook", _bodyHook.getNextHook()->toJson() ); +} + +void Component::_toJsonSignature( JsonWriter* writer ) const +// ********************************************************* +{ + jsonWrite( writer, "_net" , getNet()->getName() ); + _toJson( writer ); +} + string Component::_getString() const // ********************************* { @@ -523,10 +556,12 @@ Component::BodyHook::BodyHook(Component* component) : Inherit() { if (!component) - throw Error("Can't create " + _TName("Component::BodyHook") + " : null component"); + throw Error("Can't create " + _getTypeName() + " : null component"); - if (BODY_HOOK_OFFSET == -1) + if (BODY_HOOK_OFFSET == -1) { BODY_HOOK_OFFSET = (unsigned long)this - (unsigned long)component; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Component::BodyHook::getComponent() const @@ -541,6 +576,11 @@ string Component::BodyHook::_getString() const return "<" + _TName("Component::BodyHook") + " " + getString(getComponent()) + ">"; } +Hook* Component::BodyHook::_compToHook(Component* component) +// ************************************************************* +{ return &(component->_bodyHook); } + + // **************************************************************************************************** // Component_Hooks implementation // **************************************************************************************************** @@ -941,6 +981,16 @@ double getArea ( Component* component ) } +// **************************************************************************************************** +// JsonComponent implementation +// **************************************************************************************************** + +JsonComponent::JsonComponent(unsigned long flags) +// ********************************************** + : JsonEntity(flags) +{ + add( "_bodyHook", typeid(string) ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Contact.cpp b/hurricane/src/hurricane/Contact.cpp index ddbaa333..4ec194a5 100644 --- a/hurricane/src/hurricane/Contact.cpp +++ b/hurricane/src/hurricane/Contact.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Contact.h" #include "hurricane/Net.h" #include "hurricane/Layer.h" @@ -334,6 +336,19 @@ void Contact::_preDestroy() // trace_out(); } +void Contact::_toJson(JsonWriter* writer) const +// ******************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_anchorHook", _anchorHook.getNextHook()->toJson() ); + jsonWrite( writer, "_layer" , _layer->getName() ); + jsonWrite( writer, "_dx" , _dx ); + jsonWrite( writer, "_dy" , _dy ); + jsonWrite( writer, "_width" , _width ); + jsonWrite( writer, "_height" , _height ); +} + string Contact::_getString() const // ******************************* { @@ -373,10 +388,12 @@ Contact::AnchorHook::AnchorHook(Contact* contact) : Inherit() { if (!contact) - throw Error("Can't create " + _TName("Contact::AnchorHook") + " : null contact"); + throw Error("Can't create " + _getTypeName() + " : null contact"); - if (ANCHOR_HOOK_OFFSET == -1) - ANCHOR_HOOK_OFFSET = (unsigned long)this - (unsigned long)contact; + if (ANCHOR_HOOK_OFFSET == -1) { + ANCHOR_HOOK_OFFSET = (unsigned long)this - (unsigned long)contact; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Contact::AnchorHook::getComponent() const @@ -391,6 +408,16 @@ string Contact::AnchorHook::_getString() const return "<" + _TName("Contact::AnchorHook") + " " + getString(getComponent()) + ">"; } +Hook* Contact::AnchorHook::_compToHook(Component* component) +// *************************************************************** +{ + Contact* contact = dynamic_cast(component); + if (not contact) { + throw Error( "AnchorHook::_compToAnchorhook(): Unable to cast %s into Contact*." + , getString(component).c_str() ); + } + return &(contact->_anchorHook); +} // **************************************************************************************************** @@ -508,6 +535,54 @@ string Contact_Hooks::Locator::_getString() const return s; } + + +// **************************************************************************************************** +// JsonContact implementation +// **************************************************************************************************** + +JsonContact::JsonContact(unsigned long flags) +// ****************************************** + : JsonComponent(flags) +{ + add( "_anchorHook", typeid(string) ); + add( "_layer" , typeid(string) ); + add( "_dx" , typeid(int64_t) ); + add( "_dy" , typeid(int64_t) ); + add( "_width" , typeid(int64_t) ); + add( "_height" , typeid(int64_t) ); +} + +string JsonContact::getTypeName() const +// ************************************ +{ return "Contact"; } + +JsonContact* JsonContact::clone(unsigned long flags) const +// ******************************************************* +{ return new JsonContact ( flags ); } + +void JsonContact::toData(JsonStack& stack) +// *************************************** +{ + check( stack, "JsonContact::toData" ); + unsigned int jsonId = presetId( stack ); + + Contact* contact = Contact::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , DbU::fromDb( get(stack,"_dx" ) ) + , DbU::fromDb( get(stack,"_dy" ) ) + , DbU::fromDb( get(stack,"_width" ) ) + , DbU::fromDb( get(stack,"_height") ) + ); + + stack.addHookLink( contact->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + stack.addHookLink( contact->getAnchorHook(), jsonId, get(stack,"_anchorHook") ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, contact ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DBo.cpp b/hurricane/src/hurricane/DBo.cpp index 53431460..300434eb 100644 --- a/hurricane/src/hurricane/DBo.cpp +++ b/hurricane/src/hurricane/DBo.cpp @@ -18,8 +18,6 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// // +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | @@ -65,7 +63,6 @@ namespace Hurricane { void DBo::destroy () { _preDestroy(); - delete this; } @@ -151,6 +148,22 @@ namespace Hurricane { } + void DBo::_toJson ( JsonWriter* writer ) const + { } + + + void DBo::_toJsonSignature ( JsonWriter* writer ) const + { _toJson( writer ); } + + + void DBo::_toJsonCollections ( JsonWriter* writer ) const + { + writer->key( "+propertySet" ); + writer->startArray(); + writer->endArray(); + } + + string DBo::_getTypeName () const { return "DBo"; @@ -171,4 +184,36 @@ namespace Hurricane { } + void DBo::toJsonSignature ( JsonWriter* w ) const + { + w->startObject(); + std::string tname = "Signature." + _getTypeName(); + jsonWrite( w, "@typename", tname ); + _toJsonSignature( w ); + w->endObject(); + } + + + void DBo::toJson ( JsonWriter* w ) const + { + w->startObject(); + std::string tname = _getTypeName(); + if (w->issetFlags(JsonWriter::UsePlugReference) and (tname == "Plug")) { + tname.insert( 0, "&" ); + } + jsonWrite( w, "@typename", tname ); + _toJson( w ); + _toJsonCollections( w ); + w->endObject(); + } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + + JsonDBo::JsonDBo ( unsigned int flags ) + : JsonObject(flags) + { } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DataBase.cpp b/hurricane/src/hurricane/DataBase.cpp index a8971688..d3b8b2d9 100644 --- a/hurricane/src/hurricane/DataBase.cpp +++ b/hurricane/src/hurricane/DataBase.cpp @@ -18,6 +18,7 @@ // **************************************************************************************************** #include "hurricane/DataBase.h" +#include "hurricane/SharedPath.h" #include "hurricane/Technology.h" #include "hurricane/Library.h" #include "hurricane/Error.h" @@ -81,7 +82,7 @@ string DataBase::_getString() const } Record* DataBase::_getRecord() const -// *************************** +// ********************************* { Record* record = Inherit::_getRecord(); if (record) { @@ -100,7 +101,55 @@ DataBase* DataBase::getDB() return _db; } +Library* DataBase::getLibrary(string rpath) const +// ********************************************** +{ + Library* current = getRootLibrary(); + if (not current) return NULL; + char separator = SharedPath::getNameSeparator(); + Name childName; + size_t dot = rpath.find( separator ); + if (dot != string::npos) { + childName = rpath.substr( 0, dot ); + rpath = rpath.substr( dot+1 ); + } else + childName = rpath; + + if (childName != current->getName()) + return NULL; + + while ( dot != string::npos ) { + dot = rpath.find( separator ); + if (dot != string::npos) { + childName = rpath.substr( 0, dot ); + rpath = rpath.substr( dot+1 ); + } else + childName = rpath; + + current = current->getLibrary( childName ); + } + return current; +} + +Cell* DataBase::getCell(string rpath) const +// **************************************** +{ + + char separator = SharedPath::getNameSeparator(); + size_t dot = rpath.rfind( separator ); + string cellName = rpath.substr(dot+1); + Library* library = getLibrary( rpath.substr(0,dot) ); + Cell* cell = NULL; + + if (library) + cell = library->getCell( rpath.substr(dot+1) ); + + if (not cell and _cellLoader) return _cellLoader( rpath ); + + return cell; + +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DeepNet.cpp b/hurricane/src/hurricane/DeepNet.cpp index 00794bd0..21854632 100644 --- a/hurricane/src/hurricane/DeepNet.cpp +++ b/hurricane/src/hurricane/DeepNet.cpp @@ -49,7 +49,6 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "DeepNet". - DeepNet::DeepNet ( Occurrence& netOccurrence ) : Net(netOccurrence.getOwnerCell() ,netOccurrence.getName() @@ -122,4 +121,61 @@ namespace Hurricane { } + void DeepNet::_toJson( JsonWriter* writer ) const + { + Inherit::_toJson( writer ); + + jsonWrite( writer, "_netOccurrence", &_netOccurrence ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonDeepNet". + + JsonDeepNet::JsonDeepNet ( unsigned long flags ) + : JsonNet(flags) + { + ltrace(51) << "JsonDeepNet::JsonDeepNet()" << endl; + + add( "_netOccurrence", typeid(Occurrence) ); + } + + + JsonDeepNet::~JsonDeepNet () + { } + + + string JsonDeepNet::getTypeName () const + { return "DeepNet"; } + + + JsonDeepNet* JsonDeepNet::clone ( unsigned long flags ) const + { return new JsonDeepNet ( flags ); } + + + void JsonDeepNet::toData(JsonStack& stack) + { + ltracein(51); + + _stack = &stack; + + check( stack, "JsonDeepNet::toData" ); + presetId( stack ); + + HyperNet hyperNet ( get(stack,"_netOccurrence") ); + + _net = DeepNet::create( hyperNet ); + _net->setGlobal ( get(stack,"_isGlobal" ) ); + _net->setExternal ( get(stack,"_isExternal" ) ); + _net->setAutomatic( get(stack,"_isAutomatic") ); + _net->setType ( Net::Type (get(stack,"_type")) ); + _net->setDirection( Net::Direction(get(stack,"_direction")) ); + + setName( ".Net" ); + update( stack, _net ); + + ltraceout(51); + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DesignBlob.cpp b/hurricane/src/hurricane/DesignBlob.cpp new file mode 100644 index 00000000..2db3868b --- /dev/null +++ b/hurricane/src/hurricane/DesignBlob.cpp @@ -0,0 +1,74 @@ +// -*- mode: C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./DesignBlob.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/DesignBlob.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/DesignBlob.h" + + +namespace Hurricane { + + using std::cerr; + using std::endl; + + +// ------------------------------------------------------------------- +// Class : "DesignBlob". + + void DesignBlob::toJson( JsonWriter* w ) const + { + w->startObject(); + jsonWrite( w, "@typename", _getTypeName() ); + jsonWrite( w, "_topCell" , getTopCell()->getHierarchicalName() ); + jsonWrite( w, "_library" , DataBase::getDB()->getRootLibrary() ); + w->endObject(); + } + + +// ------------------------------------------------------------------- +// Class : "JsonDesignBlob". + + JsonDesignBlob::JsonDesignBlob ( unsigned long flags ) + : JsonObject(flags) + { + ltrace(51) << "JsonDesignblob::JsonDesignblob()" << endl; + + add( "_library", typeid(Library*) ); + add( "_topCell", typeid(string) ); + } + + + string JsonDesignBlob::getTypeName () const + { return "DesignBlob"; } + + + JsonDesignBlob* JsonDesignBlob::clone ( unsigned long flags ) const + { return new JsonDesignBlob ( flags ); } + + + void JsonDesignBlob::toData ( JsonStack& stack ) + { + check( stack, "JsonDesignBlob::toData" ); + + DesignBlob* designBlob = new DesignBlob ( DataBase::getDB()->getCell(get(stack,"_topCell")) ); + + update( stack, designBlob ); + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/Entity.cpp b/hurricane/src/hurricane/Entity.cpp index 34e74d95..8a455e71 100644 --- a/hurricane/src/hurricane/Entity.cpp +++ b/hurricane/src/hurricane/Entity.cpp @@ -28,22 +28,73 @@ namespace Hurricane { - // **************************************************************************************************** // Entity implementation // **************************************************************************************************** - unsigned int Entity::_idCounter = 0; + unsigned long Entity::_flags = 0; + unsigned int Entity::_nextId = 0; + unsigned int Entity::_idCounter = 1; unsigned int Entity::getIdCounter () { return _idCounter; } + bool Entity::inForcedIdMode () + { return _flags & ForcedIdMode; } + + + void Entity::enableForcedIdMode () + { + if (_flags & ForcedIdMode) return; + if (_idCounter != 1) { + throw Error( "Entity::enableForcedIdMode(): DataBase must be reset before forcind ids." ); + } + _flags |= ForcedIdMode; + } + + + void Entity::disableForcedIdMode () + { + if (not (_flags & ForcedIdMode)) return; + _flags &= ~ForcedIdMode; + } + + + void Entity::setNextId ( unsigned int nid ) + { + if (not (_flags & ForcedIdMode)) { + cerr << Error("Entity::setNextId(): Not in forced id mode, ignored.") << endl; + return; + } + _nextId = nid; + if (nid > _idCounter) _idCounter = nid; + _flags |= NextIdSet; + } + + + unsigned int Entity::getNextId () + { + if (_flags & ForcedIdMode) { + if (_flags & NextIdSet) { + _flags &= ~NextIdSet; + ltrace(51) << demangle(typeid(*this).name()) + << "::getNextId(): Consuming the preset id:" << _nextId << endl; + return _nextId; + } else { + throw Error("Entity::getNextId(): Next id is not set, while in forced id mode."); + } + } + + return _idCounter++; + } + + Entity::Entity() : Inherit() - , _id(_idCounter++) + , _id (getNextId()) { if (_idCounter == std::numeric_limits::max()) { throw Error( "Entity::Entity(): Identifier counter has reached it's limit (%d bits)." @@ -96,28 +147,53 @@ namespace Hurricane { //ltraceout(10); } -string Entity::_getString() const -// ****************************** -{ - string s = Inherit::_getString(); - s.insert(1, "id:"+getString(_id)+" "); - return s; -} -Record* Entity::_getRecord() const -// ************************* -{ + void Entity::setId ( unsigned int id ) + { + if (_flags & ForcedIdMode) { + _id = id; + if (_id > _idCounter) _idCounter = _id; + } else { + throw Error("Entity::setId(): Attempt to set id while not in forced id mode."); + } + } + + + void Entity::_toJson ( JsonWriter* writer ) const + { + Inherit::_toJson( writer ); + + jsonWrite( writer, "_id", getId() ); + } + + + string Entity::_getString() const + { + string s = Inherit::_getString(); + s.insert( 1, "id:"+getString(_id)+" " ); + return s; + } + + + Record* Entity::_getRecord() const + { Record* record = Inherit::_getRecord(); if (record) { - record->add(getSlot("_id", _id)); - Occurrence occurrence = Occurrence(this); - if (occurrence.hasProperty()) - record->add(getSlot("Occurrence", occurrence)); + record->add( getSlot("_id", _id) ); + Occurrence occurrence = Occurrence(this); + if (occurrence.hasProperty()) + record->add( getSlot("Occurrence", occurrence) ); } return record; -} + } + JsonEntity::JsonEntity (unsigned long flags) + : JsonDBo(flags) + { + add( "_id", typeid(uint64_t) ); + } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Hook.cpp b/hurricane/src/hurricane/Hook.cpp index aab27b2e..b20c0742 100644 --- a/hurricane/src/hurricane/Hook.cpp +++ b/hurricane/src/hurricane/Hook.cpp @@ -187,6 +187,9 @@ class Hook_SlaveHooks : public Collection { // Hook implementation // **************************************************************************************************** +map Hook::_compToHookMap; + + Hook::Hook() // ********* : _nextHook(this) @@ -385,7 +388,30 @@ Record* Hook::_getRecord() const return record; } +string Hook::toJson() const +// ************************ +{ + if (_nextHook == this) return ""; + string s = _getTypeName()+"."+getString(getComponent()->getId()); + return s; +} +void Hook::addCompToHook(const string& tname, Hook::compToHook_t converter) +// ************************************************************************ +{ + _compToHookMap.insert( make_pair(tname,converter) ); +} + +Hook* Hook::compToHook(const string& tname, Component* component) +// ************************************************************** +{ + map::const_iterator iconv = _compToHookMap.find(tname); + if (iconv == _compToHookMap.end()) { + throw Error( "Hook::fromJson(): No converter registered for type name \"%s\"" + , tname.c_str() ); + } + return (*iconv).second(component); +} // **************************************************************************************************** // Hook_Hooks implementation diff --git a/hurricane/src/hurricane/Horizontal.cpp b/hurricane/src/hurricane/Horizontal.cpp index 0d013308..67d478df 100644 --- a/hurricane/src/hurricane/Horizontal.cpp +++ b/hurricane/src/hurricane/Horizontal.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Horizontal.h" #include "hurricane/Layer.h" #include "hurricane/BasicLayer.h" @@ -173,6 +175,16 @@ void Horizontal::translate(const DbU::Unit& dy) } } +void Horizontal::_toJson(JsonWriter* writer) const +// *********************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_y" , _y ); + jsonWrite( writer, "_dxSource", _dxSource ); + jsonWrite( writer, "_dxTarget", _dxTarget ); +} + string Horizontal::_getString() const // ********************************** { @@ -191,6 +203,51 @@ Record* Horizontal::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonHorizontal implementation +// **************************************************************************************************** + +JsonHorizontal::JsonHorizontal(unsigned long flags) +// ************************************************ + : JsonSegment(flags) +{ + add( "_y" , typeid(uint64_t) ); + add( "_dxSource", typeid(uint64_t) ); + add( "_dxTarget", typeid(uint64_t) ); +} + +string JsonHorizontal::getTypeName() const +// *************************************** +{ return "Horizontal"; } + +JsonHorizontal* JsonHorizontal::clone(unsigned long flags) const +// ************************************************************* +{ return new JsonHorizontal ( flags ); } + +void JsonHorizontal::toData(JsonStack& stack) +// ****************************************** +{ + check( stack, "JsonHorizontal::toData" ); + unsigned int jsonId = presetId( stack ); + + Horizontal* horizontal = Horizontal::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , DbU::fromDb( get(stack,"_y" ) ) + , DbU::fromDb( get(stack,"_width" ) ) + , DbU::fromDb( get(stack,"_dxSource") ) + , DbU::fromDb( get(stack,"_dxTarget") ) + ); + + stack.addHookLink( horizontal->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + stack.addHookLink( horizontal->getSourceHook(), jsonId, get(stack,"_sourceHook") ); + stack.addHookLink( horizontal->getTargetHook(), jsonId, get(stack,"_targetHook") ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, horizontal ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index ae5dbb9e..260ed11b 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -20,6 +20,7 @@ #include "hurricane/Warning.h" #include "hurricane/UpdateSession.h" #include "hurricane/SharedPath.h" +#include "hurricane/DataBase.h" #include "hurricane/Instance.h" #include "hurricane/Cell.h" #include "hurricane/Net.h" @@ -30,7 +31,6 @@ namespace Hurricane { - // **************************************************************************************************** // Filters declaration & implementation // **************************************************************************************************** @@ -201,7 +201,10 @@ Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, bool // **************************************************************************************** { if (not cell) - throw Error( "Instance::create(): NULL master Cell argument." ); + throw Error( "Instance::create(): NULL owner Cell argument for %s.", getString(name).c_str() ); + + if (not masterCell) + throw Error( "Instance::create(): NULL master Cell argument for %s.", getString(name).c_str() ); // if (cell->isUniquified()) // throw Error( "Instance::create(): %s master Cell is an uniquified copy.", getString(cell).c_str() ); @@ -217,7 +220,10 @@ Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, const // ********************************************************************************************************************************************************************** { if (not cell) - throw Error( "Instance::create(): NULL master Cell argument." ); + throw Error( "Instance::create(): NULL owner Cell argument for %s.", getString(name).c_str() ); + + if (not masterCell) + throw Error( "Instance::create(): NULL master Cell argument for %s.", getString(name).c_str() ); // if (cell->isUniquified()) // throw Error( "Instance::create(): %s master Cell is an uniquified copy.", getString(cell).c_str() ); @@ -489,6 +495,15 @@ void Instance::uniquify() ) << endl; return; } + + if (not _getSharedPathMap().isEmpty()) { + cerr << Warning( "Instance::uniquify(): While uniquifying model %s of instance %s, SharedPathMap is not empty.\n" + " (Entity's Occurrences will still uses the original master Cell)" + , getString(_masterCell->getName()).c_str() + , getString(getName()).c_str() + ) << endl; + } + setMasterCell( _masterCell->getClone() ); } @@ -512,6 +527,13 @@ Instance* Instance::getClone(Cell* cloneCell) const , getPlacementStatus() ); + if (not clone->_getSharedPathMap().isEmpty()) { + cerr << Warning( "Instance::getClone(): While cloning instance %s, SharedPathMap is not empty.\n" + " (Occurrence will still uses the original instance)" + , getString(getName()).c_str() + ) << endl; + } + for( Plug* iplug : getPlugs() ) { if (iplug->isConnected()) { Plug* clonePlug = clone->getPlug( iplug->getMasterNet() ); @@ -595,6 +617,24 @@ Record* Instance::_getRecord() const return record; } +void Instance::_toJson( JsonWriter* writer ) const +// *********************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_name" , getName() ); + jsonWrite( writer, "_masterCell" , _masterCell->getHierarchicalName() ); + jsonWrite( writer, "_transformation" , &_transformation ); + jsonWrite( writer, "_placementStatus", _placementStatus ); +} + +void Instance::_toJsonCollections(JsonWriter* writer) const +// ******************************************************** +{ + jsonWrite( writer, "+plugMap", getPlugs() ); + Inherit::_toJsonCollections( writer ); +} + // **************************************************************************************************** // Instance::PlugMap implementation // **************************************************************************************************** @@ -672,13 +712,20 @@ void Instance::SharedPathMap::_setNextElement(SharedPath* sharedPath, SharedPath Instance::PlacementStatus::PlacementStatus(const Code& code) // ********************************************************* : _code(code) -{ -} +{ } Instance::PlacementStatus::PlacementStatus(const PlacementStatus& placementstatus) // ******************************************************************************* : _code(placementstatus._code) +{ } + +Instance::PlacementStatus::PlacementStatus(string s) +// ************************************************* +: _code(UNPLACED) { + if (s == "UNPLACED") _code = UNPLACED; + else if (s == "PLACED" ) _code = PLACED; + else if (s == "FIXED" ) _code = FIXED; } Instance::PlacementStatus& Instance::PlacementStatus::operator=(const PlacementStatus& placementstatus) @@ -702,6 +749,47 @@ Record* Instance::PlacementStatus::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonInstance implementation +// **************************************************************************************************** + +JsonInstance::JsonInstance(unsigned long flags) +// ******************************************** + : JsonEntity(flags) +{ + add( "_name" , typeid(string) ); + add( "_masterCell" , typeid(string) ); + add( "_transformation" , typeid(Transformation*) ); + add( "_placementStatus", typeid(string) ); + add( "+plugMap" , typeid(JsonArray) ); +} + +string JsonInstance::getTypeName() const +// ************************************* +{ return "Instance"; } + +JsonInstance* JsonInstance::clone(unsigned long flags) const +// ********************************************************* +{ return new JsonInstance ( flags ); } + +void JsonInstance::toData(JsonStack& stack) +// **************************************** +{ + check( stack, "JsonInstance::toData" ); + presetId( stack ); + + Instance* instance = Instance::create + ( get(stack,".Cell") + , get(stack,"_name") + , DataBase::getDB()->getCell( get(stack,"_masterCell") ) + , get(stack,"_transformation") + , Instance::PlacementStatus(get(stack,"_placementStatus") ) + ); + + update( stack, instance ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/JsonReader.cpp b/hurricane/src/hurricane/JsonReader.cpp new file mode 100644 index 00000000..beb50f92 --- /dev/null +++ b/hurricane/src/hurricane/JsonReader.cpp @@ -0,0 +1,821 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./JsonReader.cpp" | +// +-----------------------------------------------------------------+ + + +#include "rapidjson/filereadstream.h" +#include "rapidjson/reader.h" +// Needed for registering. May be deleted later. +#include "hurricane/DebugSession.h" +#include "hurricane/Warning.h" +#include "hurricane/JsonReader.h" +#include "hurricane/Library.h" +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/DeepNet.h" +#include "hurricane/Instance.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/DesignBlob.h" + + +namespace { + + using namespace std; + using namespace rapidjson; + using namespace Hurricane; + + class JsonReader; + + +// ------------------------------------------------------------------- +// Class : "HurricaneHandler" (declaration). + + class HurricaneHandler { + public: + HurricaneHandler ( JsonReader& ); + public: + bool Null (); + bool Bool ( bool ); + bool Int ( int ); + bool Int64 ( int64_t ); + bool Uint ( unsigned int ); + bool Uint64 ( uint64_t ); + bool Double ( double ); + bool String ( const char*, SizeType, bool copy ); + bool Key ( const char*, SizeType, bool copy ); + bool StartObject (); + bool EndObject ( SizeType ); + bool StartArray (); + bool EndArray ( SizeType ); + inline bool isDummy () const; + inline bool doCallToData () const; + inline JsonStack& stack (); + inline unsigned long flags (); + private: + enum Flags { TypenameKey = (1<<0) + }; + private: + unsigned long _state; + string _key; + string _objectName; + vector _objects; + JsonReader& _reader; + }; + + +// ------------------------------------------------------------------- +// Class : "JsonReader" (declaration). + + class JsonReader { + public: + JsonReader ( unsigned long flags ); + ~JsonReader (); + inline JsonReader* setFlags ( unsigned long mask ); + inline JsonReader* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + inline unsigned long getFlags () const; + inline JsonStack& getStack (); + void parse ( std::string fileName ); + void close (); + private: + JsonReader ( const JsonReader& ); + JsonReader& operator= ( const JsonReader& ) const; + private: + unsigned long _flags; + size_t _bufferSize; + char* _buffer; + FILE* _file; + FileReadStream* _stream; + JsonStack _stack; + Reader _reader; + HurricaneHandler _handler; + }; + + +// ------------------------------------------------------------------- +// Class : "HurricaneHandler" (definition). + + HurricaneHandler::HurricaneHandler ( JsonReader& reader ) + : _state (0) + , _key () + , _objectName() + , _objects () + , _reader (reader) + { } + + + inline JsonStack& HurricaneHandler::stack () { return _reader.getStack(); } + inline unsigned long HurricaneHandler::flags () { return _reader.getFlags(); } + + + inline bool HurricaneHandler::isDummy () const + { return _objects.empty() or _objects.back()->isDummy(); } + + + inline bool HurricaneHandler::doCallToData () const + { return not _objects.empty() and _objects.back() and not _objects.back()->isBound(); } + + + bool HurricaneHandler::Null () + { + if (isDummy()) return true; + stack().push_back( _key, NULL ); + return true; + } + + + bool HurricaneHandler::Bool ( bool v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int ( int v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int64 ( int64_t v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint ( unsigned int v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint64 ( uint64_t v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Double ( double v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::String ( const char* value, SizeType, bool copy ) + { + if (isDummy() and not (_state & TypenameKey)) return true; + if (_state & TypenameKey) { + _state &= ~TypenameKey; + + if (_key != "@typename") { + cerr << Warning("JsonReader::parse(): First field is not @typename, skipping object." ) << endl; + return true; + } + + string svalue = value; + JsonObject* object = NULL; + JsonSignature* signature = NULL; + if (svalue.compare(0,10,"Signature.") == 0) object = JsonTypes::find( "Signature" ); + else object = JsonTypes::find( value ); + + if (not object) { + // Keep the dummy object on top of the stack. + cerr << Warning( "JsonReader::parse(): Do not know how to parse type \"%s\" (ignored)." + , value ) << endl; + dynamic_cast(_objects.back())->setTypeName( value ); + } else { + // Replace the dummy object on top of the stack. + delete _objects.back(); + _objects[_objects.size()-1] = object->clone( flags() ); + _objects.back()->setName( _objectName ); + + signature = dynamic_cast( _objects.back() ); + if (signature) { + size_t dot = svalue.find('.'); + signature->setSubType( svalue.substr(dot+1) ); + } + } + + ltrace(51) << "HurricaneHandler::String() [key/typename] \"" << value << "\"." << endl; + return true; + } + + stack().push_back( _key, value ); + return true; + } + + + bool HurricaneHandler::Key ( const char* key, SizeType, bool copy ) + { + if (isDummy() and not (_state & TypenameKey)) return true; + + _key = key; + if (_state & TypenameKey) return true; + + //ltrace(51) << "HurricaneHandler::Key() key:" << _key << " _objects.size():" << _objects.size() << endl; + + if (_objects.back()) { + if ( doCallToData() and not _key.empty() and (_key[0] != '_') ) { + // The key is no longer a simple attribute of the object. + // Triggers it's creation in the Json stack. + ltrace(51) << "HurricaneHandler::key() Calling " + << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( stack() ); + } + } + + return true; + } + + + bool HurricaneHandler::StartObject () + { + ltrace(50) << "Hurricane::StartObject()" << endl; + ltracein(50); + + _state |= TypenameKey; + _objectName = (_key == ".Array") ? "" : _key; + _objects.push_back( new JsonDummy() ); + ltrace(51) << "_objects.push_back(NULL), size():" << _objects.size() << "." << endl; + + ltracein(50); + return true; + } + + + bool HurricaneHandler::EndObject ( SizeType ) + { + ltraceout(50,2); + ltrace(50) << "HurricaneHandler::EndObject()" << endl; + ltracein(50); + + _objectName.clear(); + if (not isDummy()) { + if (doCallToData()) { + ltrace(51) << "Calling " << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( stack() ); + } + if (stack().size() > 1) { + if (stack()[-1].first[0] != '_') stack().pop_back(); + } + } + + //if (_objects.size() > 1) { + ltrace(51) << "_objects.pop_back(), size():" << _objects.size() << "." << endl; + delete _objects.back(); + _objects.pop_back(); + //} + + ltraceout(50); + return true; + } + + + bool HurricaneHandler::StartArray() + { + ltrace(50) << "HurricaneHandler::StartArray() key:\"" << _key << "\"." << endl; + ltracein(50); + + _objectName.clear(); + if (_key[0] != '+') { + cerr << Warning("JsonReader::parse(): Array attributes must start by \'+\' %s.", _key.c_str() ) << endl; + return true; + } + + _key = ".Array"; + return true; + } + + bool HurricaneHandler::EndArray ( SizeType ) + { + ltraceout(50); + ltrace(50) << "HurricaneHandler::EndArray()" << endl; + ltracein(50); + + _key.clear(); + + ltraceout(50); + return true; + } + + +// ------------------------------------------------------------------- +// Class : "JsonReader" (definition). + + JsonReader::JsonReader ( unsigned long flags ) + : _flags (flags) + , _bufferSize(65536) + , _buffer (new char [_bufferSize]) + , _file (NULL) + , _stream (NULL) + , _stack () + , _reader () + , _handler (*this) + { + } + + + JsonReader::~JsonReader () + { + close(); + delete _buffer; + } + + + void JsonReader::close () + { + if (_stream) { delete _stream; _stream = NULL; } + if (_file ) { fclose(_file); _file = NULL; } + } + + + inline JsonReader* JsonReader::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonReader* JsonReader::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonReader::issetFlags ( unsigned long mask ) const { return _flags & mask; } + inline unsigned long JsonReader::getFlags () const { return _flags; } + inline JsonStack& JsonReader::getStack () { return _stack; } + + + void JsonReader::parse ( string fileName ) + { + close(); + + DebugSession::open( 50 ); + + fileName += ".json"; + _file = fopen( fileName.c_str(), "r" ); + ltrace(50) << "_file:" << _file << ", _buffer:" << (void*)_buffer << endl; + + if (not _file) { + throw Error( "JsonReader::parse(): Cannot open file \"%s\"." + , fileName.c_str() ); + } + + _stream = new FileReadStream ( _file, _buffer, _bufferSize ); + + if (issetFlags(JsonWriter::DesignBlobMode)) + Entity::enableForcedIdMode(); + _reader.Parse( *_stream, _handler ); + _stack.print( cerr ); + if (issetFlags(JsonWriter::DesignBlobMode)) + Entity::disableForcedIdMode(); + + DebugSession::close(); + close(); + } + + +} // local namespace. + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + JsonObject::JsonObject ( unsigned long flags ) + : _flags (flags) + , _name () + , _stackeds () + , _attributes () + , _collections() + , _object () + { } + + + JsonObject::~JsonObject () + { } + + + bool JsonObject::isDummy () const + { return false; } + + + void JsonObject::add ( const string& key, type_index tid ) + { + if (key.empty()) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute with an empty name, ignored." + << endl; + return; + } + if (has(key)) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute \"" << key << "\" twice, cancelled." + << endl; + return; + } + + switch ( key[0] ) { + case '.': _stackeds .push_back( JsonAttribute(key,tid) ); return; + case '_': _attributes .push_back( JsonAttribute(key,tid) ); return; + case '+': _collections.push_back( JsonAttribute(key,tid) ); return; + default: break; + } + + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + void JsonObject::remove ( const std::string& key ) + { + if (key.empty()) { + cerr << Error( "JsonObject::remove(): Attempt to remove attribute with an empty name, ignored." ) << endl; + return; + } + + switch ( key[0] ) { + case '.': + for ( auto it = _stackeds.begin() ; it != _stackeds.end() ; ++it ) + if (key == (*it).key()) { _stackeds.erase(it); break; } + break; + case '_': + for ( auto it = _attributes.begin() ; it != _attributes.end() ; ++it ) + if (key == (*it).key()) { _attributes.erase(it); break; } + break; + case '+': + for ( auto it = _collections.begin() ; it != _collections.end() ; ++it ) + if (key == (*it).key()) { _collections.erase(it); break; } + break; + } + } + + + bool JsonObject::has ( const std::string& key ) const + { + if (key.empty()) return false; + switch ( key[0] ) { + case '.': + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + if (key == _stackeds[i].key()) return true; + break; + case '_': + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + if (key == _attributes[i].key()) return true; + break; + case '+': + for ( size_t i=0 ; i<_collections.size() ; ++i ) + if (key == _collections[i].key()) return true; + break; + } + return false; + } + + + bool JsonObject::check ( JsonStack& stack, string fname ) const + { + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) { + if (not stack.rhas(_stackeds[i].key())) { + cerr << Error( "%s(): Stack is missing context element with key \"%s\"" + , fname.c_str(), _stackeds[i].key().c_str() ) << endl; + return false; + } + } + for ( size_t i=0 ; i<_attributes.size() ; ++i ) { + if (not stack.rhas(_attributes[i].key())) { + cerr << Error( "%s(): Stack is missing attribute element with key \"%s\"" + , fname.c_str(), _attributes[i].key().c_str() ) << endl; + return false; + } + } + return true; + } + + + void JsonObject::toData ( JsonStack& ) + { } + + + unsigned int JsonObject::presetId ( JsonStack& stack ) + { + unsigned int jsonId = get( stack, "_id" ); + if (issetFlags(JsonWriter::DesignBlobMode)) { + Entity::setNextId( jsonId ); + } + return jsonId; + } + + + void JsonObject::print ( ostream& o ) const + { + o << tab << "JsonObject for type: " << getTypeName() << endl; + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _stackeds[i].key() + << " type:" << _stackeds[i].tid().name() << endl; + + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _attributes[i].key() + << " type:" << _attributes[i].tid().name() << endl; + + for ( size_t i=0 ; i<_collections.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _collections[i].key() + << " type:" << _collections[i].tid().name() << endl; + } + + +// ------------------------------------------------------------------- +// Class : "JsonKey". + + JsonKey::JsonKey ( const string& key ) + : JsonObject(0) + , _key (key) + { } + + + string JsonKey::getTypeName () const { return _key; } + JsonKey* JsonKey::clone ( unsigned long ) const { return new JsonKey ( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonDummy". + + JsonDummy::JsonDummy () + : JsonObject(0) + , _typename ("dummy") + { } + + + bool JsonDummy::isDummy () const { return true; } + string JsonDummy::getTypeName () const { return _typename; } + void JsonDummy::setTypeName ( const string& name ) { _typename=name; } + JsonDummy* JsonDummy::clone ( unsigned long ) const { return new JsonDummy ( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + JsonTypes* JsonTypes::_jsonTypes = NULL; + + + JsonTypes::JsonTypes () + : _jsonObjects() + { } + + + JsonTypes::~JsonTypes () + { + for ( JsonObject* object : _jsonObjects ) delete object; + } + + + void JsonTypes::_registerType ( JsonObject* object ) + { + if (_find(object->getTypeName())) { + throw Error( "JsonTypes::_registerType(): Attempt to register <%s> twice.", object->getTypeName().c_str() ); + } + _jsonObjects.insert( object ); + } + + + JsonObject* JsonTypes::_find ( const string& tname ) + { + JsonKey key( tname ); + set::iterator it = _jsonObjects.find( &key ); + if (it != _jsonObjects.end()) return (*it); + return NULL; + } + + + void JsonTypes::registerType ( JsonObject* object ) + { + if (not _jsonTypes) initialize(); + _jsonTypes->_registerType( object ); + } + + + JsonObject* JsonTypes::find ( const string& tname ) + { + if (not _jsonTypes) initialize(); + return _jsonTypes->_find( tname ); + } + + + void JsonTypes::initialize () + { + if (_jsonTypes) return; + + _jsonTypes = new JsonTypes (); + _jsonTypes->_registerType( new JsonPoint (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonBox (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonTransformation(JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonLibrary (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonCell (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonNet (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonDeepNet (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonPlugRef (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonRoutingPad (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonContact (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonVertical (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonHorizontal (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonPad (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonInstance (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonPlug (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonOccurrence (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonSignature (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonDesignBlob (JsonWriter::RegisterMode) ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + void JsonStack::addEntity ( unsigned int jsonId, Entity* entity ) + { _entities.insert( std::make_pair(jsonId,entity) ); } + + + void JsonStack::addHookLink ( Hook* hook, unsigned int jsonId, const string& jsonNext ) + { + if (jsonNext.empty()) return; + + unsigned int id = jsonId; + string tname = hook->_getTypeName(); + + auto ielement = _hooks.find( HookKey(id,tname) ); + if (ielement == _hooks.end()) { + auto r = _hooks.insert( make_pair( HookKey(id,tname), HookElement(hook) ) ); + ielement = r.first; + (*ielement).second.setFlags( HookElement::OpenRingStart ); + } + HookElement* current = &((*ielement).second); + if (not current->hook()) current->setHook( hook ); + + hookFromString( jsonNext, id, tname ); + ielement = _hooks.find( HookKey(id,tname) ); + if (ielement == _hooks.end()) { + auto r = _hooks.insert( make_pair( HookKey(id,tname), HookElement(NULL) ) ); + ielement = r.first; + } else { + (*ielement).second.resetFlags( HookElement::OpenRingStart ); + } + current->setNext( &((*ielement).second) ); + } + + + Hook* JsonStack::getHook ( unsigned int jsonId, const std::string& tname ) const + { + auto ihook = _hooks.find( HookKey(jsonId,tname) ); + if (ihook == _hooks.end()) return NULL; + + return (*ihook).second.hook(); + } + + + bool JsonStack::hookFromString ( std::string s, unsigned int& id, std::string& tname ) + { + size_t dot = s.rfind('.'); + if (dot == string::npos) return false; + + tname = s.substr( 0, dot ); + id = stoul( s.substr(dot+1) ); + return true; + } + + + bool JsonStack::checkRings () const + { + bool status = true; + + for ( auto kv : _hooks ) { + HookElement* ringStart = &(kv.second); + if (ringStart->issetFlags(HookElement::ClosedRing)) continue; + + if (ringStart->issetFlags(HookElement::OpenRingStart)) { + cerr << Error( "JsonStack::checkRing(): Open ring found, starting with %s.\n" + " Closing the ring..." + , getString(ringStart->hook()).c_str() ) << endl; + + status = false; + HookElement* element = ringStart; + while ( true ) { + if (not element->next()) { + // The ring is open: close it (loop on ringStart). + element->setNext( ringStart ); + element->setFlags( HookElement::ClosedRing ); + + cerr << Error( "Simple open ring." ) << endl; + break; + } + if (element->next()->issetFlags(HookElement::ClosedRing)) { + // The ring is half merged with itself, or another ring. + // (i.e. *multiple* hooks pointing the *same* next element) + element->setNext( ringStart ); + element->setFlags( HookElement::ClosedRing ); + + cerr << Error( "Complex fault: ring partially merged (convergent)." ) << endl; + break; + } + element = element->next(); + } + } + } + + return status; + } + + + void JsonStack::buildRings () const + { + for ( auto kv : _hooks ) { + kv.second.hook()->_setNextHook( kv.second.next()->hook() ); + } + } + + + void JsonStack::print ( ostream& o ) const + { + o << tab << "JsonStack::print() Stack contains " << _stack.size() << " elements." << endl; + for ( size_t i=0 ; i<_stack.size() ; ++i ) { + o << "[" << right << setw(2) << i << "] key: \"" << left << setw(20) << _stack[i].first + << "\", type: \"" << demangle(_stack[i].second.type()) << "\"." << endl; + } + } + + +// ------------------------------------------------------------------- +// Function : Json Cell parser. + + Cell* jsonCellParse ( string filename ) + { + UpdateSession::open(); + + JsonReader reader ( JsonWriter::CellMode ); + reader.parse( filename ); + + UpdateSession::close(); + + const JsonStack& stack = reader.getStack(); + if (stack.rhas(".Cell")) return stack.as(".Cell"); + + return NULL; + } + + +// ------------------------------------------------------------------- +// Function : Json Blob parser. + + Cell* jsonBlobParse ( string filename ) + { + UpdateSession::open(); + + JsonReader reader ( JsonWriter::DesignBlobMode ); + reader.parse( filename ); + + UpdateSession::close(); + + const JsonStack& stack = reader.getStack(); + if (stack.rhas(".DesignBlob")) { + DesignBlob* blob = stack.as(".DesignBlob"); + Cell* cell = blob->getTopCell(); + delete blob; + return cell; + } + + return NULL; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/JsonWriter.cpp b/hurricane/src/hurricane/JsonWriter.cpp new file mode 100644 index 00000000..a00e28e0 --- /dev/null +++ b/hurricane/src/hurricane/JsonWriter.cpp @@ -0,0 +1,101 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./JsonWriter.cpp" | +// +-----------------------------------------------------------------+ + + +#include "rapidjson/filewritestream.h" +#include "rapidjson/prettywriter.h" +#include "hurricane/Commons.h" + + +//namespace Hurricane { + + typedef rapidjson::PrettyWriter JsonOfstream; + +#define _WRITER reinterpret_cast(_writer) + + +// ------------------------------------------------------------------- +// Class : "JsonWriter". + + JsonWriter::JsonWriter ( std::string fileName ) + : _flags (0) + , _bufferSize(65536) + , _buffer (new char [_bufferSize]) + , _file (NULL) + , _stream (NULL) + , _writer (NULL) + { + _file = fopen( fileName.c_str(), "w" ); + _stream = new rapidjson::FileWriteStream ( _file, _buffer, _bufferSize ); + _writer = new JsonOfstream ( *_stream ); + _WRITER->SetIndent( ' ', 2 ); + } + + + JsonWriter::~JsonWriter () + { close(); } + + + void JsonWriter::close () + { + if (_writer) { delete _WRITER; _writer = NULL; } + if (_stream) { delete _stream; _stream = NULL; } + if (_file ) { fclose(_file); _file = NULL; } + } + + + void JsonWriter::key ( const char* k ) { _WRITER->Key(k); }; + void JsonWriter::key ( std::string k ) { _WRITER->Key(k.c_str()); }; + void JsonWriter::startObject() { _WRITER->StartObject(); }; + void JsonWriter::startArray () { _WRITER->StartArray(); }; + void JsonWriter::endObject () { _WRITER->EndObject(); }; + void JsonWriter::endArray () { _WRITER->EndArray(); }; + void JsonWriter::write () { _WRITER->Null(); }; + void JsonWriter::write ( const char* s ) { _WRITER->String(s); }; + void JsonWriter::write ( const std::string* s ) { _WRITER->String(s->c_str()); }; + void JsonWriter::write ( std::string s ) { _WRITER->String(s.c_str()); }; + void JsonWriter::write ( const bool* v ) { _WRITER->Bool (*v); } + void JsonWriter::write ( bool v ) { _WRITER->Bool ( v); } + void JsonWriter::write ( const int* v ) { _WRITER->Int (*v); } + void JsonWriter::write ( int v ) { _WRITER->Int ( v); } + void JsonWriter::write ( const long* v ) { _WRITER->Int64 (*v); } + void JsonWriter::write ( long v ) { _WRITER->Int64 ( v); } + void JsonWriter::write ( const unsigned int* v ) { _WRITER->Uint (*v); } + void JsonWriter::write ( unsigned int v ) { _WRITER->Uint ( v); } + void JsonWriter::write ( const unsigned long* v ) { _WRITER->Uint64(*v); } + void JsonWriter::write ( unsigned long v ) { _WRITER->Uint64( v); } + JsonWriter* JsonWriter::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + JsonWriter* JsonWriter::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + bool JsonWriter::issetFlags ( unsigned long mask ) const { return _flags & mask; } + unsigned long JsonWriter::getFlags () const { return _flags; } + + + +//} // Hurricane namespace. diff --git a/hurricane/src/hurricane/Layer.cpp b/hurricane/src/hurricane/Layer.cpp index b2eacc8a..5f790eed 100644 --- a/hurricane/src/hurricane/Layer.cpp +++ b/hurricane/src/hurricane/Layer.cpp @@ -219,7 +219,7 @@ namespace Hurricane { } - string Layer::_getString() const + string Layer::_getString () const { string s = DBo::_getString(); s.insert(s.length() - 1, " " + getString(_name)); @@ -227,7 +227,7 @@ namespace Hurricane { } - Record* Layer::_getRecord() const + Record* Layer::_getRecord () const { Record* record = DBo::_getRecord(); if (record) { @@ -242,4 +242,7 @@ namespace Hurricane { } + const Name& Layer::_sgetName ( const Layer* layer ) + { return layer->getName(); } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Library.cpp b/hurricane/src/hurricane/Library.cpp index c348b9be..329c104b 100644 --- a/hurricane/src/hurricane/Library.cpp +++ b/hurricane/src/hurricane/Library.cpp @@ -97,6 +97,19 @@ void Library::setName(const Name& name) } } +string Library::getHierarchicalName () const +// ***************************************** +{ + string rpath; + Library* library = getLibrary(); + do { + rpath.insert( 0, getString(library->getName())+"." ); + + library = library->getLibrary(); + } while ( library ); + + return rpath + getString(getName()); +} void Library::_postCreate() // ************************ { @@ -215,6 +228,70 @@ void Library::CellMap::_setNextElement(Cell* cell, Cell* nextCell) const cell->_setNextOfLibraryCellMap(nextCell); }; +void Library::_toJson(JsonWriter* w) const +// *************************************** +{ + Inherit::_toJson( w ); + + jsonWrite( w, "_name" , getName() ); + jsonWrite( w, "+cellMap" , getCells() ); + jsonWrite( w, "+libraryMap", getLibraries() ); +} + + +// **************************************************************************************************** +// JsonLibrary implementation +// **************************************************************************************************** + +JsonLibrary::JsonLibrary(unsigned long flags) +// ************************************ + : JsonDBo(flags) +{ + add( ".Library" , typeid(Library*) ); + add( "_name" , typeid(string) ); + add( "+cellMap" , typeid(JsonArray) ); + add( "+libraryMap", typeid(JsonArray) ); +} + +string JsonLibrary::getTypeName() const +// ********************************* +{ return "Library"; } + +JsonLibrary* JsonLibrary::clone(unsigned long flags) const +// ************************************************* +{ return new JsonLibrary ( flags ); } + +void JsonLibrary::toData(JsonStack& stack) +// *************************************** +{ + check( stack, "JsonLibrary::toData" ); + + Name libName ( get ( stack, "_name" ) ); + Library* parent = get( stack, ".Library" ); + if (not parent) + parent = get( stack, "_library" ); + + Library* library = NULL; + if (parent) { + library = parent->getLibrary( libName ); + if (not library) + library = Library::create( parent, libName ); + } else { + library = DataBase::getDB()->getRootLibrary(); + if (not library) + library = Library::create( DataBase::getDB(), libName ); + else { + if (library->getName() != libName) { + throw Error( "JsonLibrary::toData(): Root library name discrepency, \"%s\" vs. \"%s\"." + , getString(library->getName()).c_str() + , getString(libName).c_str() + ); + } + } + } + + update( stack, library ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index 56e75993..3bf41410 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -738,6 +738,37 @@ Record* Net::_getRecord() const return record; } +void Net::_toJson(JsonWriter* writer) const +// **************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_name" , getName() ); + jsonWrite( writer, "_isGlobal" , isGlobal() ); + jsonWrite( writer, "_isExternal" , isExternal() ); + jsonWrite( writer, "_isAutomatic" , isAutomatic() ); + jsonWrite( writer, "_type" , getString(getType()) ); + jsonWrite( writer, "_direction" , getString(getDirection()) ); +} + +void Net::_toJsonSignature(JsonWriter* writer) const +// ************************************************* +{ + jsonWrite( writer, "_name", getName() ); +} + +void Net::_toJsonCollections(JsonWriter* writer) const +// *************************************************** +{ + jsonWrite( writer, "+aliases", getAliases() ); + writer->setFlags( JsonWriter::UsePlugReference ); + jsonWrite( writer, "+componentSet", getComponents() ); + writer->resetFlags( JsonWriter::UsePlugReference ); + + Inherit::_toJsonCollections( writer ); +} + + // **************************************************************************************************** // Net::Type implementation // **************************************************************************************************** @@ -745,13 +776,22 @@ Record* Net::_getRecord() const Net::Type::Type(const Code& code) // ****************************** : _code(code) -{ -} +{ } Net::Type::Type(const Type& type) // ****************************** : _code(type._code) +{ } + +Net::Type::Type(string s) +// ********************** +: _code(UNDEFINED) { + if (s == "UNDEFINED") _code = UNDEFINED; + else if (s == "LOGICAL" ) _code = LOGICAL; + else if (s == "CLOCK" ) _code = CLOCK; + else if (s == "POWER" ) _code = POWER; + else if (s == "GROUND" ) _code = GROUND; } Net::Type& Net::Type::operator=(const Type& type) @@ -784,13 +824,23 @@ Record* Net::Type::_getRecord() const Net::Direction::Direction(const Code& code) // **************************************** : _code(code) -{ -} +{ } Net::Direction::Direction(const Direction& direction) // ************************************************** : _code(direction._code) +{ } + +Net::Direction::Direction(string s) +// ******************************** +: _code(UNDEFINED) { + if (s.size() > 3) { + if (s[0] == 'i') *this |= DirIn; + if (s[0] == 'o') *this |= DirOut; + if (s[0] == 't') *this |= ConnTristate; + if (s[0] == 'w') *this |= ConnWiredOr; + } } Net::Direction& Net::Direction::operator=(const Direction& direction) @@ -1008,6 +1058,81 @@ string Net_SlavePlugs::Locator::_getString() const return s; } + + +// **************************************************************************************************** +// JsonNet implementation +// **************************************************************************************************** + +JsonNet::JsonNet(unsigned long flags) +// ********************************** + : JsonEntity (flags) + , _autoMaterialize(not Go::autoMaterializationIsDisabled()) + , _net (NULL) + , _stack (NULL) +{ + if (flags & JsonWriter::RegisterMode) return; + + ltrace(51) << "JsonNet::JsonNet()" << endl; + + add( "_name" , typeid(string) ); + add( "_isGlobal" , typeid(bool) ); + add( "_isExternal" , typeid(bool) ); + add( "_isAutomatic" , typeid(bool) ); + add( "_type" , typeid(string) ); + add( "_direction" , typeid(string) ); + add( "+aliases" , typeid(JsonArray) ); + add( "+componentSet", typeid(JsonArray) ); + + ltrace(51) << "Disabling auto-materialization (" << _autoMaterialize << ")." << endl; + Go::disableAutoMaterialization(); +} + +JsonNet::~JsonNet() +// **************** +{ + _stack->checkRings(); + _stack->buildRings(); + _stack->clearHookLinks(); + + _net->materialize(); + + if (_autoMaterialize) { + Go::enableAutoMaterialization(); + ltrace(51) << "Enabling auto-materialization." << endl; + } +} + +string JsonNet::getTypeName() const +// ********************************* +{ return "Net"; } + +JsonNet* JsonNet::clone(unsigned long flags) const +// *********************************************** +{ return new JsonNet ( flags ); } + +void JsonNet::toData(JsonStack& stack) +// *********************************** +{ + ltracein(51); + + _stack = &stack; + + check( stack, "JsonNet::toData" ); + presetId( stack ); + + _net = Net::create( get(stack,".Cell") , get(stack,"_name") ); + _net->setGlobal ( get(stack,"_isGlobal" ) ); + _net->setExternal ( get(stack,"_isExternal" ) ); + _net->setAutomatic( get(stack,"_isAutomatic") ); + _net->setType ( Net::Type (get(stack,"_type")) ); + _net->setDirection( Net::Direction(get(stack,"_direction")) ); + + update( stack, _net ); + + ltraceout(51); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Occurrence.cpp b/hurricane/src/hurricane/Occurrence.cpp index 077a2969..f3201ffd 100644 --- a/hurricane/src/hurricane/Occurrence.cpp +++ b/hurricane/src/hurricane/Occurrence.cpp @@ -261,6 +261,23 @@ string Occurrence::getCompactString() const return s; } +void Occurrence::toJson(JsonWriter* w) const +// ****************************************** +{ + w->startObject(); + jsonWrite( w, "@typename", "Occurrence" ); + jsonWrite( w, "_path" , getPath().getJsonString(w->getFlags()) ); + + w->key( "_entity" ); + if (not w->issetFlags(JsonWriter::DesignBlobMode)) { + getEntity()->toJsonSignature( w ); + } else { + jsonWrite( w, getEntity()->getId() ); + } + + w->endObject(); +} + Record* Occurrence::_getRecord() const // **************************** { @@ -307,6 +324,77 @@ string Occurrence::getName() const return description; } +JsonOccurrence::JsonOccurrence(unsigned long flags) +// ************************************************ + : JsonObject(flags) +{ + add( ".Cell" , typeid(Cell*) ); + add( "_path" , typeid(string) ); + + if (issetFlags(JsonWriter::DesignBlobMode)) { + add( "_entity", typeid(uint64_t) ); + } else { + add( "_entity", typeid(Entity*) ); + } +} + +JsonOccurrence* JsonOccurrence::clone(unsigned long flags) const +// ************************************************************* +{ return new JsonOccurrence ( flags ); } + +string JsonOccurrence::getTypeName() const +// *************************************** +{ return "Occurrence"; } + +void JsonOccurrence::toData(JsonStack& stack) +// ****************************************** +{ + check( stack, "JsonOccurrence::toData" ); + + Path path; + Entity* entity = NULL; + if (issetFlags(JsonWriter::DesignBlobMode)) { + entity = stack.getEntity( get(stack,"_entity") ); + + //Cell* cell = get( stack, ".Cell" ); + Instance* instance = NULL; + char separator = SharedPath::getNameSeparator(); + string pathIds = get( stack, "_path" ); + unsigned long id; + size_t dot = pathIds.find( separator ); + + if (dot != string::npos) { + id = stoul( pathIds.substr( 0, dot ) ); + pathIds = pathIds.substr( dot+1 ); + } else + id = stol( pathIds ); + + instance = stack.getEntity(id); + if (not instance) + throw Error( "JsonOccurrence::toData(): No Instance id:lu% (or not an Instance) in stack LUT.", id ); + path = Path( instance ); + + while ( dot != string::npos ) { + dot = pathIds.find( separator ); + if (dot != string::npos) { + id = stoul( pathIds.substr( 0, dot ) ); + pathIds = pathIds.substr( dot+1 ); + } else + id = stol( pathIds ); + + instance = stack.getEntity(id); + if (not instance) + throw Error( "JsonOccurrence::toData(): No Instance id:lu% (or not an Instance) in stack LUT.", id ); + path = Path( path, instance ); + } + } else { + entity = get(stack,"_entity"); + path = Path( get(stack,".Cell"), get(stack,"_path") ); + } + + Occurrence occurrence ( entity, path ); + update( stack, occurrence ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Pad.cpp b/hurricane/src/hurricane/Pad.cpp index 2ad7aa36..7c23d9e9 100644 --- a/hurricane/src/hurricane/Pad.cpp +++ b/hurricane/src/hurricane/Pad.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Pad.h" #include "hurricane/Net.h" #include "hurricane/BasicLayer.h" @@ -117,6 +119,15 @@ void Pad::setBoundingBox(const Box& boundingBox) } } +void Pad::_toJson(JsonWriter* writer) const +// **************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_layer" , _layer->getName() ); + jsonWrite( writer, "_boundingBox", &_boundingBox ); +} + string Pad::_getString() const // *************************** { @@ -137,6 +148,45 @@ Record* Pad::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonPad implementation +// **************************************************************************************************** + +JsonPad::JsonPad(unsigned long flags) +// ********************************** + : JsonComponent(flags) +{ + add( "_layer" , typeid(string) ); + add( "_boundingBox", typeid(Box) ); +} + +string JsonPad::getTypeName() const +// ******************************** +{ return "Pad"; } + +JsonPad* JsonPad::clone(unsigned long flags) const +// *********************************************** +{ return new JsonPad ( flags ); } + +void JsonPad::toData(JsonStack& stack) +// *********************************** +{ + check( stack, "JsonPad::toData" ); + unsigned int jsonId = presetId( stack ); + + Pad* pad = Pad::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , get(stack,".Box") + ); + + stack.addHookLink( pad->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, pad ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Path.cpp b/hurricane/src/hurricane/Path.cpp index 36a17c38..49a35b4f 100644 --- a/hurricane/src/hurricane/Path.cpp +++ b/hurricane/src/hurricane/Path.cpp @@ -258,6 +258,25 @@ string Path::getCompactString() const return s; } +string Path::getJsonString(unsigned long flags) const +// ************************************************** +{ + if (isEmpty()) return ""; + + string s; + if (flags & JsonWriter::DesignBlobMode) { + //s += getString(getOwnerCell()->getId()) + "::"; + s += getString(_sharedPath->getJsonString(flags)); + //s += "::" + getString(getMasterCell()->getId()); + } else { + //s += getString(getOwnerCell()->getName()) + "::"; + s += getString(_sharedPath->getJsonString(flags)); + //s += "::" + getString(getMasterCell()->getName()); + } + + return s; +} + string Path::_getString() const // **************************** { @@ -282,7 +301,6 @@ Record* Path::_getRecord() const } - } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Plug.cpp b/hurricane/src/hurricane/Plug.cpp index e65a2c5a..6027c3de 100644 --- a/hurricane/src/hurricane/Plug.cpp +++ b/hurricane/src/hurricane/Plug.cpp @@ -153,11 +153,12 @@ void Plug::setNet(Net* net) Plug* Plug::_create(Instance* instance, Net* masterNet) // **************************************************** { - Plug* plug = new Plug(instance, masterNet); + if (Entity::inForcedIdMode()) Entity::setNextId( 0 ); - plug->_postCreate(); + Plug* plug = new Plug(instance, masterNet); - return plug; + plug->_postCreate(); + return plug; } void Plug::_postCreate() @@ -190,6 +191,18 @@ void Plug::_preDestroy() // trace_out(); } +void Plug::_toJson(JsonWriter* writer) const +// ***************************************** +{ + if (writer->issetFlags(JsonWriter::UsePlugReference)) { + jsonWrite( writer, "_id" , getId() ); + jsonWrite( writer, "_instance", getInstance()->getName() ); + } else { + Inherit::_toJson( writer ); + jsonWrite( writer, "_masterNet", getMasterNet()->getName() ); + } +} + string Plug::_getString() const // **************************** { @@ -217,6 +230,109 @@ string Plug::getName() const + getString(_masterNet->getName()); } + + +// **************************************************************************************************** +// JsonPlug implementation +// **************************************************************************************************** + +JsonPlug::JsonPlug(unsigned long flags) +// ************************************ + : JsonComponent(flags) +{ + add( "_masterNet", typeid(string) ); +} + +string JsonPlug::getTypeName() const +// ********************************* +{ return "Plug"; } + +JsonPlug* JsonPlug::clone(unsigned long flags) const +// ************************************************* +{ return new JsonPlug ( flags ); } + +void JsonPlug::toData(JsonStack& stack) +// ************************************ +{ +// We are parsing an Instance. +// Plugs are automatically createds whith the Instance. +// Here we add the Plug to the stack's entity table that +// associates the Json Ids to the actual Hurricane ones. +// At the same time, we perform some coherency checking +// (i.e. the same Plug already exists). + +// For now, simply discard "_id" & "_propertySet". + check( stack, "JsonPlug::toData" ); + + Instance* instance = get(stack,".Instance"); + Plug* plug = NULL; + if (instance) { + Net* masterNet = instance->getMasterCell()->getNet( get(stack,"_masterNet") ); + if (not masterNet) { + cerr << Error( "JsonPlug::toData(): Incoherency, instance %s master doesn't containt net %s." + , getString(instance->getName()).c_str() + , get(stack,"_masterNet").c_str() + ) << endl; + } else { + unsigned int jsonId = get(stack,"_id"); + plug = instance->getPlug( masterNet ); + if (issetFlags(JsonWriter::DesignBlobMode)) + plug->forceId( jsonId ); + stack.addHookLink( plug->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + } + } else { + cerr << Error( "JsonPlug::toData(): Cannot find \".Instance\" in stack, skipping." ) << endl; + } + ltrace(51) << "Instance Plug contents ignored for now." << endl; + + update( stack, plug ); +} + + + +// **************************************************************************************************** +// JsonPlugRef implementation +// **************************************************************************************************** + +JsonPlugRef::JsonPlugRef(unsigned long flags) +// ****************************************** + : JsonObject(flags) +{ + add( ".Net" , typeid(Net*) ); + add( "_id" , typeid(uint64_t) ); + add( "_instance", typeid(string) ); +} + +string JsonPlugRef::getTypeName() const +// ************************************ +{ return "&Plug"; } + +JsonPlugRef* JsonPlugRef::clone(unsigned long flags) const +// ******************************************************* +{ return new JsonPlugRef ( flags ); } + +void JsonPlugRef::toData(JsonStack& stack) +// *************************************** +{ + check( stack, "JsonPlugRef::toData" ); + +// We are parsing a Net, perform only a "Plug::setNet()". + Net* net = get(stack,".Net"); + Instance* instance = net->getCell()->getInstance( get(stack,"_instance") ); + unsigned int id = get(stack,"_id"); + + Plug* plug = stack.getEntity(id); + if (plug) { + plug->setNet( net ); + } else { + cerr << Error( "JsonPlugRef::toData(): No Plug id:%u in instance %s, while building net %s." + , id, getString(instance->getName()).c_str(), getString(net->getName()).c_str() + ) << endl; + } + + update( stack, plug ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Point.cpp b/hurricane/src/hurricane/Point.cpp index 902dee17..7f6f5a05 100644 --- a/hurricane/src/hurricane/Point.cpp +++ b/hurricane/src/hurricane/Point.cpp @@ -123,7 +123,40 @@ Record* Point::_getRecord() const return record; } +void Point::toJson ( JsonWriter* w ) const +// **************************************** +{ + w->startObject(); + jsonWrite( w, "@typename", "Point" ); + jsonWrite( w, "_x", getX() ); + jsonWrite( w, "_y", getY() ); + w->endObject(); +} +JsonPoint::JsonPoint(unsigned long flags) +// ************************************** + : JsonObject(flags) +{ + add( "_x", typeid(int64_t) ); + add( "_y", typeid(int64_t) ); +} + +JsonPoint* JsonPoint::clone(unsigned long flags) const +// *************************************************** +{ return new JsonPoint ( flags ); } + +string JsonPoint::getTypeName() const +// ********************************** +{ return "Point"; } + +void JsonPoint::toData(JsonStack& stack) +// ************************************* +{ + check( stack, "JsonPoint::toData" ); + Point point ( DbU::fromDb(get(stack,"_x")) + , DbU::fromDb(get(stack,"_y")) ); + update( stack, point ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/RoutingPad.cpp b/hurricane/src/hurricane/RoutingPad.cpp index 91b18cc8..81465ada 100644 --- a/hurricane/src/hurricane/RoutingPad.cpp +++ b/hurricane/src/hurricane/RoutingPad.cpp @@ -38,6 +38,7 @@ #include "hurricane/Segment.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" +#include "hurricane/Pad.h" #include "hurricane/Cell.h" #include "hurricane/Instance.h" #include "hurricane/Warning.h" @@ -50,6 +51,9 @@ namespace Hurricane { using std::ostringstream; +// ------------------------------------------------------------------- +// Class : "RoutingPad". + RoutingPad::RoutingPad ( Net* net, Occurrence occurrence ) : Inherit (net) , _occurrence(occurrence) @@ -61,18 +65,27 @@ namespace Hurricane { if ( not net ) throw Error ("Can't create RoutingPad : NULL net"); if ( not occurrence.isValid() ) throw Error ("Can't create RoutingPag : Invalid occurrence"); - Plug* plug = NULL; - Pin* pin = NULL; - Contact* contact = NULL; + Plug* plug = NULL; + Pin* pin = NULL; + Contact* contact = NULL; + Horizontal* horizontal = NULL; + Vertical* vertical = NULL; + Pad* pad = NULL; if ( (plug = dynamic_cast(occurrence.getEntity()) ) == NULL) { if ( (pin = dynamic_cast(occurrence.getEntity()) ) == NULL) { - contact = dynamic_cast(occurrence.getEntity()); + if ( (contact = dynamic_cast(occurrence.getEntity()) ) == NULL) { + if ( (horizontal = dynamic_cast(occurrence.getEntity()) ) == NULL) { + if ( (vertical = dynamic_cast(occurrence.getEntity()) ) == NULL) { + pad = dynamic_cast(occurrence.getEntity()); + } + } + } } } - if ( (not plug) and (not pin) and (not contact) ) - throw Error ("Can't create RoutingPad : Plug, Pin, or Contact Occurrence *required*"); + if ( (not plug) and (not pin) and (not contact) and (not horizontal) and (not vertical) and (not pad) ) + throw Error ("Can't create RoutingPad : Plug, Pin, Contact, Horizontal, Vertical or Pad Occurrence *required*"); RoutingPad* routingPad = new RoutingPad( net, occurrence ); routingPad->_postCreate(); @@ -156,8 +169,9 @@ namespace Hurricane { Box RoutingPad::getBoundingBox ( const BasicLayer* basicLayer ) const { Component* component = _getEntityAsComponent(); - if ( component ) + if ( component ) { return _occurrence.getPath().getTransformation().getBox ( component->getBoundingBox(basicLayer) ); + } return Box(getPosition()); } @@ -175,8 +189,9 @@ namespace Hurricane { Point RoutingPad::getPosition () const { Component* component = _getEntityAsComponent(); - if (component) + if (component) { return _occurrence.getPath().getTransformation().getPoint( component->getCenter() ); + } return Point(); } @@ -233,6 +248,12 @@ namespace Hurricane { } + void RoutingPad::_toJson ( JsonWriter* writer ) const + { + Inherit::_toJson( writer ); + jsonWrite( writer, "_occurrence", &_occurrence ); + } + string RoutingPad::_getString () const { string s = Inherit::_getString(); @@ -379,4 +400,37 @@ namespace Hurricane { } +// ------------------------------------------------------------------- +// Class : "JsonRoutingPad". + + JsonRoutingPad::JsonRoutingPad ( unsigned long flags ) + : JsonComponent(flags) + { + add( "_occurrence", typeid(Occurrence) ); + } + + string JsonRoutingPad::getTypeName () const + { return "RoutingPad"; } + + + JsonRoutingPad* JsonRoutingPad::clone ( unsigned long flags ) const + { return new JsonRoutingPad ( flags ); } + + + void JsonRoutingPad::toData ( JsonStack& stack ) + { + check( stack, "JsonRoutingPad::toData" ); + unsigned int jsonId = presetId( stack ); + + RoutingPad* rp = RoutingPad::create + ( get (stack,".Net") + , get(stack,"_occurrence") + ); + + stack.addHookLink( rp->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + + update( stack, rp ); + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Segment.cpp b/hurricane/src/hurricane/Segment.cpp index 1eba7e0c..9635d86b 100644 --- a/hurricane/src/hurricane/Segment.cpp +++ b/hurricane/src/hurricane/Segment.cpp @@ -306,6 +306,17 @@ void Segment::_preDestroy() // trace_out(); } +void Segment::_toJson(JsonWriter* writer) const +// ******************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_sourceHook", _sourceHook.getNextHook()->toJson() ); + jsonWrite( writer, "_targetHook", _targetHook.getNextHook()->toJson() ); + jsonWrite( writer, "_layer" , _layer->getName() ); + jsonWrite( writer, "_width" , _width ); +} + string Segment::_getString() const // ******************************* { @@ -318,7 +329,7 @@ string Segment::_getString() const } Record* Segment::_getRecord() const -// ************************** +// ******************************** { Record* record = Inherit::_getRecord(); if (record) { @@ -332,6 +343,7 @@ Record* Segment::_getRecord() const return record; } + // **************************************************************************************************** // Segment::SourceHook implementation // **************************************************************************************************** @@ -342,11 +354,13 @@ Segment::SourceHook::SourceHook(Segment* segment) // ********************************************** : Inherit() { - if (!segment) - throw Error("Can't create " + _TName("Segment::SourceHook") + " (null segment)"); + if (!segment) + throw Error("Can't create " + _getTypeName() + " (null segment)"); - if (SOURCE_HOOK_OFFSET == -1) - SOURCE_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + if (SOURCE_HOOK_OFFSET == -1) { + SOURCE_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Segment::SourceHook::getComponent() const @@ -361,6 +375,16 @@ string Segment::SourceHook::_getString() const return "<" + _TName("Segment::SourceHook") + " " + getString(getComponent()) + ">"; } +Hook* Segment::SourceHook::_compToHook(Component* component) +// *************************************************************** +{ + Segment* segment = dynamic_cast(component); + if (not segment) { + throw Error( "SourceHook::_compToHook(): Unable to cast %s into Segment*." + , getString(component).c_str() ); + } + return &(segment->_sourceHook); +} // **************************************************************************************************** @@ -376,8 +400,10 @@ Segment::TargetHook::TargetHook(Segment* segment) if (!segment) throw Error("Can't create " + _TName("Segment::TargetHook") + " (null segment)"); - if (TARGET_HOOK_OFFSET == -1) - TARGET_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + if (TARGET_HOOK_OFFSET == -1) { + TARGET_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Segment::TargetHook::getComponent() const @@ -392,6 +418,18 @@ string Segment::TargetHook::_getString() const return "<" + _TName("Segment::TargetHook") + " " + getString(getComponent()) + ">"; } +Hook* Segment::TargetHook::_compToHook(Component* component) +// *************************************************************** +{ + Segment* segment = dynamic_cast(component); + if (not segment) { + throw Error( "TargetHook::_compToHook(): Unable to cast %s into Segment*." + , getString(component).c_str() ); + } + return &(segment->_targetHook); +} + + // **************************************************************************************************** // Segment_Hooks implementation // **************************************************************************************************** @@ -633,6 +671,20 @@ string Segment_Anchors::Locator::_getString() const +// **************************************************************************************************** +// JsonSegment implementation +// **************************************************************************************************** + +JsonSegment::JsonSegment(unsigned long flags) +// ****************************************** + : JsonComponent(flags) +{ + add( "_sourceHook", typeid(string) ); + add( "_targetHook", typeid(string) ); + add( "_layer" , typeid(uint64_t) ); + add( "_width" , typeid(uint64_t) ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/SharedPath.cpp b/hurricane/src/hurricane/SharedPath.cpp index 04d83f7e..a0a97575 100644 --- a/hurricane/src/hurricane/SharedPath.cpp +++ b/hurricane/src/hurricane/SharedPath.cpp @@ -186,6 +186,23 @@ string SharedPath::getName() const return name; } +string SharedPath::getJsonString(unsigned long flags) const +// ******************************************************** +{ + string name = ""; + SharedPath* sharedPath = (SharedPath*)this; + while (sharedPath) { + if (flags & JsonWriter::DesignBlobMode) + name += getString(sharedPath->getHeadInstance()->getId()); + else + name += getString(sharedPath->getHeadInstance()->getName()); + + sharedPath = sharedPath->getTailSharedPath(); + if (sharedPath) name += getNameSeparator(); + } + return name; +} + Cell* SharedPath::getOwnerCell() const // *********************************** { diff --git a/hurricane/src/hurricane/Signature.cpp b/hurricane/src/hurricane/Signature.cpp new file mode 100644 index 00000000..cbc1dc27 --- /dev/null +++ b/hurricane/src/hurricane/Signature.cpp @@ -0,0 +1,167 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Authors : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Signature.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Path.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" +#include "hurricane/Signature.h" + + +namespace Hurricane { + + using std::ostringstream; + + +// ------------------------------------------------------------------- +// Class : "Signature". + + void Signature::setLayer ( const std::string& layer ) + { + _layer = DataBase::getDB()->getTechnology()->getLayer( layer ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonSignature". + + JsonSignature::JsonSignature ( unsigned long flags ) + : JsonObject (flags) + , _subTypeName("unset") + { } + + string JsonSignature::getTypeName () const + { return "Signature"; } + + + void JsonSignature::setSubType ( const std::string& subTypeName ) + { + clear(); + _subTypeName = subTypeName; + + if (_subTypeName == "Instance") { + add( "_instance" , typeid(string) ); + } else if (_subTypeName == "Net") { + add( "_name", typeid(string) ); + } else if (_subTypeName == "Plug") { + add( "_masterNet", typeid(string) ); + } else if (_subTypeName == "Contact") { + add( "_net", typeid(string) ); + JsonContact jobject (0); + copyAttrs( &jobject ); + } else if (_subTypeName == "Vertical") { + add( "_net", typeid(string) ); + JsonVertical jobject (0); + copyAttrs( &jobject ); + } else if (_subTypeName == "Horizontal") { + add( "_net", typeid(string) ); + JsonHorizontal jobject (0); + copyAttrs( &jobject ); + } + } + + JsonSignature* JsonSignature::clone ( unsigned long flags ) const + { return new JsonSignature ( flags ); } + + + void JsonSignature::toData ( JsonStack& stack ) + { + ltrace(51) << (void*)this << " _subTypeName:" << _subTypeName << endl; + + check( stack, "JsonSignature::toData" ); + + Cell* ownerCell = get ( stack, ".Cell" ); + string pathName = get( stack, "_path" ); + Path path ( ownerCell, pathName ); + Cell* masterCell = path.getMasterCell(); + Entity* entity = NULL; + + if (_subTypeName == "Instance") { + entity = masterCell->getInstance( get(stack,"_name") ); + } else if (_subTypeName == "Net") { + entity = masterCell->getNet( get(stack,"_name") ); + } else if (_subTypeName == "Plug") { + Net* masterNet = masterCell->getNet( get(stack,"_masterNet") ); + entity = path.getTailInstance()->getPlug( masterNet ); + } else if (_subTypeName == "Contact") { + Signature signature; + signature.setType ( Signature::TypeContact ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer" ) ); + signature.setDim( Signature::ContactDx , get(stack,"_dx" ) ); + signature.setDim( Signature::ContactDy , get(stack,"_dy" ) ); + signature.setDim( Signature::ContactWidth , get(stack,"_width" ) ); + signature.setDim( Signature::ContactHeight, get(stack,"_height") ); + entity = masterCell->getEntity( signature ); + } else if (_subTypeName == "Vertical") { + Signature signature; + signature.setType ( Signature::TypeVertical ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer") ); + signature.setDim( Signature::VerticalWidth , get(stack,"_width" ) ); + signature.setDim( Signature::VerticalX , get(stack,"_x" ) ); + signature.setDim( Signature::VerticalDySource, get(stack,"_dySource") ); + signature.setDim( Signature::VerticalDyTarget, get(stack,"_dyTarget") ); + entity = masterCell->getEntity( signature ); + } else if (_subTypeName == "Horizontal") { + Signature signature; + signature.setType ( Signature::TypeHorizontal ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer") ); + signature.setDim( Signature::HorizontalWidth , get(stack,"_width" ) ); + signature.setDim( Signature::HorizontalY , get(stack,"_y" ) ); + signature.setDim( Signature::HorizontalDxSource, get(stack,"_dxSource") ); + signature.setDim( Signature::HorizontalDxTarget, get(stack,"_dxTarget") ); + entity = masterCell->getEntity( signature ); + } else if (_subTypeName == "Pad") { + Signature signature; + signature.setType ( Signature::TypePad ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer") ); + Box bb = get(stack, "_boundingBox" ); + signature.setDim( Signature::PadXMin, bb.getXMin() ); + signature.setDim( Signature::PadYMin, bb.getYMin() ); + signature.setDim( Signature::PadXMax, bb.getXMax() ); + signature.setDim( Signature::PadYMax, bb.getYMax() ); + entity = masterCell->getEntity( signature ); + } + + update( stack, entity ); + } + + +} // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Tabulation.cpp b/hurricane/src/hurricane/Tabulation.cpp index 39a0ac42..c491fe0c 100644 --- a/hurricane/src/hurricane/Tabulation.cpp +++ b/hurricane/src/hurricane/Tabulation.cpp @@ -17,7 +17,8 @@ // not, see . // **************************************************************************************************** -#include "hurricane/Tabulation.h" + +#include "hurricane/Commons.h" namespace Hurricane { diff --git a/hurricane/src/hurricane/Transformation.cpp b/hurricane/src/hurricane/Transformation.cpp index fd83a29a..904779e0 100644 --- a/hurricane/src/hurricane/Transformation.cpp +++ b/hurricane/src/hurricane/Transformation.cpp @@ -255,6 +255,16 @@ Record* Transformation::_getRecord() const return record; } +void Transformation::toJson ( JsonWriter* w ) const +// ************************************************* +{ + w->startObject(); + jsonWrite( w, "@typename", "Transformation" ); + jsonWrite( w, "_tx", getTx() ); + jsonWrite( w, "_ty", getTy() ); + jsonWrite( w, "_orientation", getString( &(getOrientation().getCode()) ) ); + w->endObject(); +} // **************************************************************************************************** @@ -273,6 +283,20 @@ Transformation::Orientation::Orientation(const Orientation& orientation) { } +Transformation::Orientation::Orientation(const string& s) +// ****************************************************** +: _code(ID) +{ + if (s == "ID") _code = ID; + else if (s == "R1") _code = R1; + else if (s == "R2") _code = R2; + else if (s == "R3") _code = R3; + else if (s == "MX") _code = MX; + else if (s == "XR") _code = XR; + else if (s == "MY") _code = MY; + else if (s == "YR") _code = YR; +} + Transformation::Orientation& Transformation::Orientation::operator=(const Orientation& orientation) // ************************************************************************************************ { @@ -295,6 +319,38 @@ Record* Transformation::Orientation::_getRecord() const } +// **************************************************************************************************** +// Transformation::Orientation implementation +// **************************************************************************************************** + +JsonTransformation::JsonTransformation(unsigned long flags) +// ******************************************************** + : JsonObject(flags) +{ + add( "_tx" , typeid(int64_t) ); + add( "_ty" , typeid(int64_t) ); + add( "_orientation", typeid(string) ); +} + +string JsonTransformation::getTypeName() const +// ******************************************* +{ return "Transformation"; } + +JsonTransformation* JsonTransformation::clone(unsigned long flags) const +// ********************************************************************* +{ return new JsonTransformation ( flags ); } + +void JsonTransformation::toData(JsonStack& stack) +// ********************************************** +{ + check( stack, "JsonTransformation::toData" ); + + Transformation transf ( get(stack,"_tx") + , get(stack,"_ty") + , Transformation::Orientation(get(stack,"_orientation")) ); + + update( stack, transf ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Vertical.cpp b/hurricane/src/hurricane/Vertical.cpp index 8a0b0948..e34b14eb 100644 --- a/hurricane/src/hurricane/Vertical.cpp +++ b/hurricane/src/hurricane/Vertical.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Vertical.h" #include "hurricane/Layer.h" #include "hurricane/BasicLayer.h" @@ -176,6 +178,16 @@ void Vertical::translate(const DbU::Unit& dx) } } +void Vertical::_toJson(JsonWriter* writer) const +// ******************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_x" , _x ); + jsonWrite( writer, "_dySource", _dySource ); + jsonWrite( writer, "_dyTarget", _dyTarget ); +} + string Vertical::_getString() const // ******************************** { @@ -194,6 +206,51 @@ Record* Vertical::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonVertical implementation +// **************************************************************************************************** + +JsonVertical::JsonVertical(unsigned long flags) +// ******************************************** + : JsonSegment(flags) +{ + add( "_x" , typeid(uint64_t) ); + add( "_dySource", typeid(uint64_t) ); + add( "_dyTarget", typeid(uint64_t) ); +} + +string JsonVertical::getTypeName() const +// ************************************* +{ return "Vertical"; } + +JsonVertical* JsonVertical::clone(unsigned long flags) const +// ********************************************************* +{ return new JsonVertical ( flags ); } + +void JsonVertical::toData(JsonStack& stack) +// **************************************** +{ + check( stack, "JsonVertical::toData" ); + unsigned int jsonId = presetId( stack ); + + Vertical* vertical = Vertical::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , DbU::fromDb( get(stack,"_x" ) ) + , DbU::fromDb( get(stack,"_width" ) ) + , DbU::fromDb( get(stack,"_dySource") ) + , DbU::fromDb( get(stack,"_dyTarget") ) + ); + + stack.addHookLink( vertical->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + stack.addHookLink( vertical->getSourceHook(), jsonId, get(stack,"_sourceHook") ); + stack.addHookLink( vertical->getTargetHook(), jsonId, get(stack,"_targetHook") ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, vertical ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/grenier/json/DBo.cpp b/hurricane/src/hurricane/grenier/json/DBo.cpp new file mode 100644 index 00000000..1302dc93 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/DBo.cpp @@ -0,0 +1,198 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Remy Escassut | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./DBo.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Property.h" +#include "hurricane/DBo.h" +#include "hurricane/Quark.h" +#include "hurricane/Error.h" + + +namespace Hurricane { + + +// ------------------------------------------------------------------- +// Class : "Hurricane::DBo". + + + DBo::DBo (): _propertySet() + { } + + + DBo::~DBo () + { } + + + void DBo::_postCreate () + { } + + + void DBo::_preDestroy () + { + clearProperties (); + } + + + void DBo::destroy () + { + _preDestroy(); + + delete this; + } + + + Property* DBo::getProperty ( const Name& name ) const + { + set::const_iterator iterator = _propertySet.begin(); + while ( iterator != _propertySet.end() ) { + Property* property = *iterator; + if (property->getName() == name) return property; + ++iterator; + } + return NULL; + } + + + Properties DBo::getProperties () const + { + return getCollection(_propertySet); + } + + + void DBo::put ( Property* property ) + { + if ( !property ) + throw Error("DBo::put(): Can't put property : NULL property."); + + Property* oldProperty = getProperty ( property->getName() ); + if ( property != oldProperty ) { + if ( oldProperty ) { + _propertySet.erase ( oldProperty ); + oldProperty->onReleasedBy ( this ); + } + _propertySet.insert ( property ); + property->onCapturedBy ( this ); + } + } + + + void DBo::remove ( Property* property ) + { + if ( !property ) + throw Error("DBo::remove(): Can't remove property : NULL property."); + + if ( _propertySet.find(property) != _propertySet.end() ) { + _propertySet.erase ( property ); + property->onReleasedBy ( this ); + if ( dynamic_cast(this) && _propertySet.empty() ) + destroy(); + } + } + + + void DBo::removeProperty ( const Name& name ) + { + Property* property = getProperty ( name ); + if ( property ) { + _propertySet.erase ( property ); + property->onReleasedBy ( this ); + if ( dynamic_cast(this) && _propertySet.empty() ) + destroy(); + } + } + + + void DBo::_onDestroyed ( Property* property ) + { + if ( property && ( _propertySet.find(property) != _propertySet.end() ) ) { + _propertySet.erase ( property ); + if ( dynamic_cast(this) && _propertySet.empty() ) + destroy(); + } + } + + + void DBo::clearProperties () + { + while ( !_propertySet.empty() ) { + Property* property = *_propertySet.begin(); + _propertySet.erase ( property ); + property->onReleasedBy ( this ); + } + } + + + void DBo::_toJson ( JsonWriter* writer ) const + { + // writer->key( "+propertySet" ); + // writer->startArray(); + // writer->endArray(); + } + + + void DBo::_toJsonProperties ( JsonWriter* writer ) const + { + writer->key( "+propertySet" ); + writer->startArray(); + writer->endArray(); + } + + + string DBo::_getTypeName () const + { + return "DBo"; + } + + + string DBo::_getString () const + { + return "<" + _getTypeName() + ">"; + } + + + Record* DBo::_getRecord () const + { + Record* record = new Record ( getString(this) ); + record->add ( getSlot("_propertySet", &_propertySet) ); + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + + JsonDBo::JsonDBo ( unsigned long flags ) + : JsonObject() + { + add( "+propertySet", &DBo::getProperties ); + } + + +} // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/grenier/json/DBo.h b/hurricane/src/hurricane/grenier/json/DBo.h new file mode 100644 index 00000000..01edbabd --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/DBo.h @@ -0,0 +1,114 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Remy Escassut | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/DBo.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_DBO_H +#define HURRICANE_DBO_H + +#include "hurricane/DBos.h" +#include "hurricane/Name.h" +#include "hurricane/Properties.h" + + +namespace Hurricane { + + class JsonDBo; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::DBo". + + class DBo { + friend class JsonDBo; + public: + virtual void destroy (); + inline set& _getPropertySet (); + void _onDestroyed ( Property* property ); + Property* getProperty ( const Name& ) const; + Properties getProperties () const; + inline bool hasProperty () const; + void put ( Property* ); + void remove ( Property* ); + void removeProperty ( const Name& ); + void clearProperties (); + virtual void _toJson ( JsonWriter* ) const; + virtual void _toJsonProperties ( JsonWriter* ) const; + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + + private: + mutable set _propertySet; + + protected: + DBo (); + virtual ~DBo (); + virtual void _postCreate (); + virtual void _preDestroy (); + + private: + DBo ( const DBo& ); + DBo& operator= ( const DBo& ); + }; + + +// Inline Functions. + inline set& DBo::_getPropertySet () { return _propertySet; } + inline bool DBo::hasProperty () const { return !_propertySet.empty(); } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + + class JsonDBo : public JsonObject { + public: + JsonDBo ( unsigned long flags ); +}; + + +} // Hurricane namespace. + + +// inline void jsonWrite ( JsonWriter* w, const Hurricane::DBo* dbo ) +// { +// w->startObject(); +// std::string tname = dbo->_getTypeName(); +// if (w->issetFlags(JsonWriter::UsePlugReference) and (tname == "Plug")) { +// tname.insert( 0, "&" ); +// } +// jsonWrite( w, "@typename", tname ); +// dbo->_toJson( w ); +// dbo->_toJsonProperties( w ); +// w->endObject(); +// } + +INSPECTOR_P_SUPPORT(Hurricane::DBo); + +#endif // HURRICANE_DBO_H diff --git a/hurricane/src/hurricane/grenier/json/JsonReader.cpp b/hurricane/src/hurricane/grenier/json/JsonReader.cpp new file mode 100644 index 00000000..74c3b5c0 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/JsonReader.cpp @@ -0,0 +1,650 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./JsonReader.cpp" | +// +-----------------------------------------------------------------+ + + +#include "rapidjson/filereadstream.h" +#include "rapidjson/reader.h" +// Needed for registering. May be deleted later. +#include "hurricane/DebugSession.h" +#include "hurricane/Warning.h" +#include "hurricane/JsonReader.h" +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/Instance.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" + + +namespace { + + using namespace std; + using namespace rapidjson; + using namespace Hurricane; + + +// ------------------------------------------------------------------- +// Struct : "HurricaneHandler". + + class HurricaneHandler { + public: + HurricaneHandler ( JsonStack& ); + public: + bool Null (); + bool Bool ( bool ); + bool Int ( int ); + bool Int64 ( int64_t ); + bool Uint ( unsigned int ); + bool Uint64 ( uint64_t ); + bool Double ( double ); + bool String ( const char*, SizeType, bool copy ); + bool Key ( const char*, SizeType, bool copy ); + bool StartObject (); + bool EndObject ( SizeType ); + bool StartArray (); + bool EndArray ( SizeType ); + bool doCallToData () const; + private: + enum Flags { TypenameKey = (1<<0) + , ArrayMode = (1<<2) + , SkipObject = (1<<3) + , SkipArray = (1<<4) + , SkipMask = SkipObject | SkipArray + }; + private: + unsigned long _state; + string _key; + string _objectName; + vector _objects; + JsonStack& _stack; + }; + + + HurricaneHandler::HurricaneHandler ( JsonStack& stack ) + : _state (0) + , _key () + , _objectName() + , _objects () + , _stack (stack) + { } + + + bool HurricaneHandler::doCallToData () const + { return not _objects.empty() and _objects.back() and not _objects.back()->isCreated(); } + + + bool HurricaneHandler::Null () + { + //if (not _objects.empty()) ltrace(59) << "null _objects.back(): " << _objects.back() << endl; + + if (_state & SkipMask) return true; + _stack.push_back( _key, NULL ); + return true; + } + + + bool HurricaneHandler::Bool ( bool v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int ( int v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int64 ( int64_t v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint ( unsigned int v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint64 ( uint64_t v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Double ( double v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::String ( const char* value, SizeType, bool copy ) + { + if (_state & SkipMask) return true; + if (_state & TypenameKey) { + _state &= ~TypenameKey; + + JsonObject* object = JsonTypes::find( value ); + _objects[_objects.size()-1] = object->clone(); + + if (not object) { + cerr << Warning("JsonReader::parse(): Do not know how to parse type %s.", value ) << endl; + _state |= SkipObject; + } else { + _objects[_objects.size()-1]->setName( _objectName ); + } + + ltrace(51) << "HurricaneHandler::String() [key/typename] " << value << endl; + return true; + } + + _stack.push_back( _key, value ); + return true; + } + + + bool HurricaneHandler::Key ( const char* key, SizeType, bool copy ) + { + _key = key; + if (_state & SkipMask) { + _key.clear(); + return true; + } + + if (_state & TypenameKey) { + if (_key != "@typename") { + _state |= SkipObject; + _key.clear(); + } + return true; + } + + //ltrace(51) << "HurricaneHandler::Key() key:" << _key << " _objects.size():" << _objects.size() << endl; + + if (_objects.back()) { + if ( doCallToData() and not _key.empty() and (_key[0] != '_') ) { + // The key is no longer a simple attribute of the object. + // Triggers it's creation in the Json stack. + ltrace(51) << "HurricaneHandler::key() Calling " + << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( _stack ); + } + } + + return true; + } + + + bool HurricaneHandler::StartObject () + { + ltrace(50) << "Hurricane::StartObject()" << endl; + ltracein(50); + + _state |= TypenameKey; + // if (doCallToData()) { + // ltrace(51) << "Calling " << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + // _objects.back()->toData( _stack ); + // } + _objectName = (_key == ".Array") ? "" : _key; + _objects.push_back( NULL ); + ltrace(51) << "_objects.push_back(NULL), size():" << _objects.size() << "." << endl; + + ltracein(50); + return true; + } + + + bool HurricaneHandler::EndObject ( SizeType ) + { + ltraceout(50,2); + ltrace(50) << "HurricaneHandler::EndObject()" << endl; + ltracein(50); + + _objectName.clear(); + if (_state & SkipObject) { + _state &= ~SkipObject; + } else { + if (doCallToData()) { + ltrace(51) << "Calling " << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( _stack ); + } + if (_objects.size() > 1) { + ltrace(51) << "_objects.pop_back(), size():" << _objects.size() << "." << endl; + delete _objects.back(); + _objects.pop_back(); + } + if (_stack.size() > 1) { + if (_stack[-1].first[0] != '_') _stack.pop_back(); + } + } + ltraceout(50); + return true; + } + + + bool HurricaneHandler::StartArray() + { + ltrace(50) << "HurricaneHandler::StartArray() key:\"" << _key << "\"." << endl; + ltracein(50); + + _objectName.clear(); + if (_key.empty()) { _state |= SkipArray; return true; } + if (_key[0] != '+') { + cerr << Warning("JsonReader::parse(): Array attributes must start by \'+\' %s.", _key.c_str() ) << endl; + _state |= SkipArray; + return true; + } + + _state |= ArrayMode; + _key = ".Array"; + + return true; + } + + bool HurricaneHandler::EndArray ( SizeType ) + { + ltraceout(50); + ltrace(50) << "HurricaneHandler::EndArray()" << endl; + ltracein(50); + + _state &= ~(ArrayMode | SkipArray); + _key.clear(); + + ltraceout(50); + return true; + } + + +// ------------------------------------------------------------------- +// Class : "JsonReader". + + class JsonReader { + public: + enum Mode { CellMode = (1<<0) }; + public: + JsonReader (); + ~JsonReader (); + JsonReader* setFlags ( unsigned long mask ); + JsonReader* resetFlags ( unsigned long mask ); + bool issetFlags ( unsigned long mask ) const; + const JsonStack& getStack () const; + void parse ( std::string fileName, unsigned int flags ); + void close (); + private: + JsonReader ( const JsonReader& ); + JsonReader& operator= ( const JsonReader& ) const; + private: + unsigned long _flags; + size_t _bufferSize; + char* _buffer; + FILE* _file; + FileReadStream* _stream; + JsonStack _stack; + Reader _reader; + HurricaneHandler _handler; + }; + + + JsonReader::JsonReader () + : _flags (0) + , _bufferSize(65536) + , _buffer (new char [_bufferSize]) + , _file (NULL) + , _stream (NULL) + , _stack () + , _reader () + , _handler (_stack) + { + } + + + JsonReader::~JsonReader () + { + close(); + delete _buffer; + } + + + void JsonReader::close () + { + if (_stream) { delete _stream; _stream = NULL; } + if (_file ) { fclose(_file); _file = NULL; } + } + + + const JsonStack& JsonReader::getStack () const + { return _stack; } + + + void JsonReader::parse ( string fileName, unsigned int flags ) + { + close(); + + DebugSession::open( 50 ); + + fileName += ".json"; + _file = fopen( fileName.c_str(), "r" ); + cerr << "_file:" << _file << ", _buffer:" << (void*)_buffer << endl; + _stream = new FileReadStream ( _file, _buffer, _bufferSize ); + + _reader.Parse( *_stream, _handler ); + _stack.print( cerr ); + + DebugSession::close(); + close(); + } + + +} // local namespace. + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "JsonAttribute". + + JsonAttribute::~JsonAttribute () + { } + + +// ------------------------------------------------------------------- +// Class : "JsonStacked". + + JsonStacked::~JsonStacked () + { } + + + type_index JsonStacked::tid () const + { return typeid(JsonStacked); } + + + void JsonStacked::toJson ( JsonWriter*, boost::any object ) const + { + cerr << Error("JsonStacked::toJson() is a dummy method that should never be called.") << endl; + } + + + JsonStacked* JsonStacked::clone () const + { return new JsonStacked( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + JsonObject::JsonObject () + : _name () + , _stackeds () + , _attributes () + , _collections() + , _object () + { } + + + JsonObject::JsonObject ( const JsonObject& other ) + : _name (other._name) + , _stackeds () + , _attributes () + , _collections() + , _object () + { + for ( JsonAttribute* attribute : other._stackeds ) _stackeds.push_back( attribute->clone() ); + for ( JsonAttribute* attribute : other._attributes ) _stackeds.push_back( attribute->clone() ); + for ( JsonAttribute* attribute : other._collections ) _stackeds.push_back( attribute->clone() ); + } + + + JsonObject::~JsonObject () + { clear(); } + + + bool JsonObject::isJsonObject () const + { return _flags & IsJsonObject; } + + + void JsonObject::remove ( const std::string& key ) + { + if (key.empty()) { + cerr << Error( "JsonObject::remove(): Attempt to remove attribute with an empty name, ignored." ) << endl; + return; + } + + switch ( key[0] ) { + case '.': + for ( auto it = _stackeds.begin() ; it != _stackeds.end() ; ++it ) + if (key == (*it)->key()) { delete (*it); _stackeds.erase(it); break; } + break; + case '_': + for ( auto it = _attributes.begin() ; it != _attributes.end() ; ++it ) + if (key == (*it)->key()) { delete (*it); _attributes.erase(it); break; } + break; + case '+': + for ( auto it = _collections.begin() ; it != _collections.end() ; ++it ) + if (key == (*it)->key()) { delete (*it); _collections.erase(it); break; } + break; + } + } + + + bool JsonObject::has ( const std::string& key ) const + { + if (key.empty()) return false; + switch ( key[0] ) { + case '.': + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + if (key == _stackeds[i]->key()) return true; + break; + case '_': + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + if (key == _attributes[i]->key()) return true; + break; + case '+': + for ( size_t i=0 ; i<_collections.size() ; ++i ) + if (key == _collections[i]->key()) return true; + break; + } + return false; + } + + + bool JsonObject::check ( JsonStack& stack, string fname ) const + { + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) { + if (not stack.rhas(_stackeds[i]->key())) { + cerr << Error( "%s(): Stack is missing context element with key \"%s\"" + , fname.c_str(), _stackeds[i]->key().c_str() ) << endl; + return false; + } + } + for ( size_t i=0 ; i<_attributes.size() ; ++i ) { + if (not stack.rhas(_attributes[i]->key())) { + cerr << Error( "%s(): Stack is missing attribute element with key \"%s\"" + , fname.c_str(), _attributes[i]->key().c_str() ) << endl; + return false; + } + } + return true; + } + + + void JsonObject::toData ( JsonStack& ) + { } + + + void JsonObject::print ( ostream& o ) const + { + o << tab << "JsonObject for type: " << getTypeName() << endl; + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _stackeds[i]->key() + << " type:" << _stackeds[i]->tid().name() << endl; + + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _attributes[i]->key() + << " type:" << _attributes[i]->tid().name() << endl; + + for ( size_t i=0 ; i<_collections.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _collections[i]->key() + << " type:" << _collections[i]->tid().name() << endl; + } + + + JsonKey::JsonKey ( const string& key ) + : JsonObject() + , _key (key) + { } + + + string JsonKey::getTypeName () const + { return _key; } + + + JsonKey* JsonKey::clone () const + { return new JsonKey ( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + JsonTypes* JsonTypes::_jsonTypes = NULL; + + + JsonTypes::JsonTypes () + : _jsonObjects() + { } + + + JsonTypes::~JsonTypes () + { + for ( JsonObject* object : _jsonObjects ) delete object; + } + + + void JsonTypes::_registerType ( JsonObject* object ) + { + if (_find(object->getTypeName())) { + throw Error( "JsonTypes::_registerType(): Attempt to register <%s> twice.", object->getTypeName().c_str() ); + } + _jsonObjects.insert( object ); + } + + + JsonObject* JsonTypes::_find ( const string& tname ) + { + JsonKey key( tname ); + set::iterator it = _jsonObjects.find( &key ); + if (it != _jsonObjects.end()) return (*it); + return NULL; + } + + + void JsonTypes::registerType ( JsonObject* object ) + { + if (not _jsonTypes) initialize(); + _jsonTypes->_registerType( object ); + } + + + JsonObject* JsonTypes::find ( const string& tname ) + { + if (not _jsonTypes) initialize(); + return _jsonTypes->_find( tname ); + } + + + void JsonTypes::initialize () + { + if (_jsonTypes) return; + + _jsonTypes = new JsonTypes (); + _jsonTypes->_registerType( new JsonPoint (0) ); + _jsonTypes->_registerType( new JsonBox (0) ); + _jsonTypes->_registerType( new JsonTransformation(0) ); + _jsonTypes->_registerType( new JsonCell (0) ); + _jsonTypes->_registerType( new JsonNet (0) ); + _jsonTypes->_registerType( new JsonPlugRef (0) ); + _jsonTypes->_registerType( new JsonRoutingPad (0) ); + _jsonTypes->_registerType( new JsonContact (0) ); + _jsonTypes->_registerType( new JsonVertical (0) ); + _jsonTypes->_registerType( new JsonHorizontal (0) ); + _jsonTypes->_registerType( new JsonPad (0) ); + _jsonTypes->_registerType( new JsonInstance (0) ); + _jsonTypes->_registerType( new JsonPlug (0) ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + void JsonStack::addEntity ( unsigned int jsonId, Entity* entity ) + { _entities.insert( std::make_pair(jsonId,entity) ); } + + + void JsonStack::print ( ostream& o ) const + { + o << tab << "JsonStack::print() Stack contains " << _stack.size() << " elements." << endl; + for ( size_t i=0 ; i<_stack.size() ; ++i ) { + o << "[" << right << setw(2) << i << "] key: \"" << left << setw(20) << _stack[i].first + << "\", type: \"" << demangle(_stack[i].second.type()) << "\"." << endl; + } + } + + +// ------------------------------------------------------------------- +// Function : Json Cell parser. + + Cell* jsonCellParse ( string filename ) + { + JsonReader reader; + reader.parse( filename, JsonReader::CellMode ); + + const JsonStack& stack = reader.getStack(); + if (stack.rhas(".Cell")) return stack.as(".Cell"); + return NULL; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/grenier/json/JsonReader.h b/hurricane/src/hurricane/grenier/json/JsonReader.h new file mode 100644 index 00000000..79e2d5f0 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/JsonReader.h @@ -0,0 +1,790 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/JsonReader.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_JSON_READER_H +#define HURRICANE_JSON_READER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Hurricane { + + class Entity; + class Cell; + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonStack; + class JsonArray { }; + + +// ------------------------------------------------------------------- +// Class : "JsonAttribute". + + class JsonAttribute { + public: + inline JsonAttribute ( const std::string& key, unsigned long flags ); + virtual ~JsonAttribute (); + inline std::string key () const; + virtual std::type_index tid () const = 0; + virtual void toJson ( JsonWriter*, boost::any object ) const = 0; + virtual JsonAttribute* clone () const = 0; + inline void setFlags ( unsigned long mask ); + inline void resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + private: + std::string _key; + unsigned long _flags; + }; + + inline JsonAttribute::JsonAttribute ( const std::string& key, unsigned long flags ): _key(key), _flags(flags) { } + inline std::string JsonAttribute::key () const { return _key; } + inline void JsonAttribute::setFlags ( unsigned long mask ) { _flags |= mask; } + inline void JsonAttribute::resetFlags ( unsigned long mask ) { _flags &= ~mask; } + inline bool JsonAttribute::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + +// ------------------------------------------------------------------- +// Class : "JsonStacked". + + class JsonStacked : public JsonAttribute { + public: + inline JsonStacked ( const std::string& key ); + virtual ~JsonStacked (); + virtual std::type_index tid () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + virtual JsonStacked* clone () const; + }; + + inline JsonStacked::JsonStacked ( const std::string& key ): JsonAttribute(key,0) { } + + +// ------------------------------------------------------------------- +// Class : "JsonAnyAttribute". + + template + class JsonAnyAttribute : public JsonAttribute { + public: + JsonAnyAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ); + virtual ~JsonAnyAttribute (); + virtual std::type_index tid () const; + virtual JsonAnyAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T C::* _attribute; + }; + + + template + JsonAnyAttribute::JsonAnyAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + { } + + template + JsonAnyAttribute::~JsonAnyAttribute () + { } + + template + std::type_index JsonAnyAttribute::tid () + { return typeid(T); } + + template + JsonAnyAttribute* JsonAnyAttribute::clone () const + { return new JsonAnyAttribute( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonStrAttribute". + + template + class JsonStrAttribute : public JsonAttribute { + public: + JsonStrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ); + virtual ~JsonStrAttribute (); + virtual std::type_index tid () const; + virtual JsonStrAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T C::* _attribute; + }; + + + template + JsonStrAttribute::JsonStrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + { } + + template + JsonStrAttribute::~JsonStrAttribute () + { } + + template + std::type_index JsonStrAttribute::tid () + { return typeid(T); } + + template + JsonStrAttribute* JsonStrAttribute::clone () const + { return new JsonStrAttribute( *this ); } + + template + void JsonStrAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), getString( boost::any_cast(object)->*_attribute ) ); } + + +// ------------------------------------------------------------------- +// Class : "JsonFtrrAttribute". + + template + class JsonFtrrAttribute : public JsonAttribute { + public: + JsonFtrrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + , std::function tr + ); + virtual ~JsonFtrrAttribute (); + virtual std::type_index tid () const; + virtual JsonFtrrAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T C::* _attribute; + std::function _tr; + }; + + + template + JsonFtrrAttribute::JsonFtrrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + , std::function tr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + , _tr (tr) + { } + + template + JsonFtrrAttribute::~JsonFtrrAttribute () + { } + + template + std::type_index JsonFtrrAttribute::tid () + { return typeid(T); } + + template + JsonFtrrAttribute* JsonFtrrAttribute::clone () const + { return new JsonFtrrAttribute( *this ); } + + template + void JsonFtrrAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), _tr( boost::any_cast(object)->*_attribute ) ); } + + +// ------------------------------------------------------------------- +// Class : "JsonFtrpAttribute". + + template + class JsonFtrpAttribute : public JsonAttribute { + public: + JsonFtrpAttribute ( const std::string& key + , unsigned long flags + , T* C::* attr + , std::function tr + ); + virtual ~JsonFtrpAttribute (); + virtual std::type_index tid () const; + virtual JsonFtrpAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T* C::* _attribute; + std::function _tr; + }; + + + template + JsonFtrpAttribute::JsonFtrpAttribute ( const std::string& key + , unsigned long flags + , T* C::* attr + , std::function tr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + , _tr (tr) + { } + + template + JsonFtrpAttribute::~JsonFtrpAttribute () + { } + + template + std::type_index JsonFtrpAttribute::tid () + { return typeid(T); } + + template + JsonFtrpAttribute* JsonFtrpAttribute::clone () const + { return new JsonFtrpAttribute( *this ); } + + template + void JsonFtrpAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), _tr( boost::any_cast(object)->*_attribute ) ); } + + +// ------------------------------------------------------------------- +// Class : "JsonMethAttribute". + + template + class JsonMethAttribute : public JsonAttribute { + public: + JsonMethAttribute ( const std::string& key + , unsigned long flags + , R (C::* meth )() const + ); + virtual ~JsonMethAttribute (); + virtual std::type_index tid () const; + virtual JsonMethAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + R (C::* _meth)() const; + }; + + + template + JsonMethAttribute::JsonMethAttribute ( const std::string& key + , unsigned long flags + , R (C::* meth)() const + ) + : JsonAttribute(key,flags) + , _meth (meth) + { } + + template + JsonMethAttribute::~JsonMethAttribute () + { } + + template + std::type_index JsonMethAttribute::tid () + { return typeid(R); } + + template + JsonMethAttribute* JsonMethAttribute::clone () const + { return new JsonMethAttribute( *this ); } + + template + void JsonMethAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), (boost::any_cast(object)->*_meth)() ); } + + +// ------------------------------------------------------------------- +// Class : "JsonAnyAttribute". + +#define JSON_POD_ATTRIBUTE(pod_t) \ + template \ + class JsonAnyAttribute : public JsonAttribute { \ + public: \ + JsonAnyAttribute ( const std::string& key \ + , unsigned long flags \ + , pod_t C::* attr \ + ); \ + virtual ~JsonAnyAttribute (); \ + virtual std::type_index tid () const; \ + virtual JsonAnyAttribute* clone () const; \ + virtual void toJson ( JsonWriter*, boost::any object ) const; \ + private: \ + pod_t C::* _attribute; \ + }; \ + \ + \ + template \ + JsonAnyAttribute::JsonAnyAttribute ( const std::string& key \ + , unsigned long flags \ + , pod_t C::* attr \ + ) \ + : JsonAttribute(key,flags) \ + , _attribute (attr) \ + { } \ + \ + template \ + JsonAnyAttribute::~JsonAnyAttribute () \ + { } \ + \ + template \ + std::type_index JsonMethAttribute::tid () \ + { return typeid(pod_t); } \ + \ + template \ + JsonAnyAttribute* JsonAnyAttribute::clone () const \ + { return new JsonAnyAttribute( *this ); } \ + \ + template \ + void JsonAnyAttribute::toJson ( JsonWriter* w, boost::any object ) const \ + { jsonWrite( w, key(), boost::any_cast(object)->*_attribute ); } + + +// Build a specialized JsonAnyAttribute for all POD types. + JSON_POD_ATTRIBUTE(bool) + JSON_POD_ATTRIBUTE(int) + JSON_POD_ATTRIBUTE(long) + JSON_POD_ATTRIBUTE(unsigned int) + JSON_POD_ATTRIBUTE(unsigned long) + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonObject { + public: + enum Flags { IsJsonObject = (1<<0) + , UsePlugReference = (1<<1) + , UseReference = (1<<3) + }; + public: + JsonObject (); + JsonObject ( const JsonObject& ); + virtual ~JsonObject (); + virtual std::string getTypeName () const = 0; + inline std::string getStackName () const; + virtual bool isJsonObject () const; + bool check ( JsonStack&, string fname ) const; + void print ( std::ostream& ) const; + bool has ( const std::string& key ) const; + template + inline T get ( JsonStack&, const std::string& key ) const; + void add ( const std::string& key, unsigned long flags ); + template + void add ( const std::string& key, T C::* attr, unsigned long flags ); + template + void add ( const std::string& key, T C::* attr, R(*tr)(T&), unsigned long flags ); + template + void add ( const std::string& key, T* C::* attr, R(*tr)(T*), unsigned long flags ); + template + void add ( const std::string& key, R(C::* meth)() const, unsigned long flags ); + template + void addS ( const std::string& key, T C::* attr, unsigned long flags ); + void remove ( const std::string& key ); + template + T access ( const std::string& key ); + inline void clear (); + inline std::string getName () const; + inline void setName ( const string& ); + template inline T& getObject () const; + template inline void setObject ( T& ) ; + inline bool isCreated () const; + virtual JsonObject* clone () const = 0; + template void toJson ( JsonWriter*, C* object ) const; + virtual void toData ( JsonStack& ); + template inline void update ( JsonStack&, T ); + inline void setFlags ( unsigned long mask ); + inline void resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + protected: + inline bool _checkKey ( const std::string& key ) const; + protected: + unsigned long _flags; + std::string _name; + std::vector _stackeds; + std::vector _attributes; + std::vector _collections; + boost::any _object; + }; + + + inline bool JsonObject::isCreated () const { return not _object.empty(); } + inline std::string JsonObject::getName () const { return _name; } + inline void JsonObject::setName ( const string& name ) { _name=name; } + inline void JsonObject::setFlags ( unsigned long mask ) { _flags |= mask; } + inline void JsonObject::resetFlags ( unsigned long mask ) { _flags &= ~mask; } + inline bool JsonObject::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + inline std::string JsonObject::getStackName () const + { return (_name.empty()) ? std::string(".")+getTypeName(): _name; } + + template inline T& JsonObject::getObject () const + { return boost::any_cast(_object); } + + template inline void JsonObject::setObject ( T& t ) + { _object = t; } + + + bool JsonObject::checkKey ( const std::string& key ) const + { + if (key.empty()) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute with an empty name, ignored." + << endl; + return false; + } + if (has(key)) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute \"" << key << "\" twice, cancelled." + << endl; + return false; + } + return true; + } + + + void JsonObject::add ( const std::string& key ) + { + if ( _checkKey(key) and (key[0] == '.') ) { + _stackeds.push_back( new JsonStacked(key) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Stack requirement key \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, T C::* attr, unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonAnyAttribute(key,flags,attr) ); + case '+': _attributes.push_back( new JsonAnyAttribute(key,flags,attr) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, T C::* attr, R(*tr)(T&), unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonFtrrAttribute(key,flags,attr,std::function(tr)) ); + case '+': _attributes.push_back( new JsonFtrrAttribute(key,flags,attr,std::function(tr)) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, T* C::* attr, R(*tr)(T*), unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonFtrpAttribute(key,flags,attr,std::function(tr)) ); + case '+': _attributes.push_back( new JsonFtrpAttribute(key,flags,attr,std::function(tr)) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, R(C::*meth)() const, unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonMethAttribute(key,flags,meth) ); + case '+': _attributes.push_back( new JsonMethAttribute(key,flags,meth) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::addS( const std::string& key, T C::* attr, unsigned int flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonStrAttribute(key,flags,attr) ); + return; + } + cerr << "[ERROR] JsonObject::addS(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template void JsonObject::toJson ( JsonWriter* w, C* object ) const + { + if (isJsonObject()) { + w->startObject(); + jsonWrite( w, "@typename", getTypeName() ); + for ( JsonAttribute* attribute : _attributes ) attribute ->toJson( w, object ); + for ( JsonAttribute* collection : _collections ) collection->toJson( w, object ); + w->endObject(); + } + } + + + inline void JsonObject::clear () + { + for ( JsonAttribute* attribute : _stackeds ) delete attribute; + for ( JsonAttribute* attribute : _attributes ) delete attribute; + for ( JsonAttribute* attribute : _collections ) delete attribute; + + _stackeds .clear(); + _attributes .clear(); + _collections.clear(); + } + + + class JsonKey : public JsonObject { + public: + inline JsonKey ( const std::string& ); + virtual std::string getTypeName () const; + virtual JsonKey* clone () const; + private: + std::string _key; + }; + + +} // Hurricane namespace. + + +namespace std { + + template<> + struct less { + inline bool operator() ( const Hurricane::JsonObject* lhs, const Hurricane::JsonObject* rhs ) + { return lhs->getTypeName() < rhs->getTypeName(); } + }; + +} // std namespace. + + +namespace Hurricane { + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + class JsonTypes { + public: + static void initialize (); + static void registerType ( JsonObject* ); + static JsonObject* find ( const std::string& tname ); + private: + JsonTypes (); + ~JsonTypes (); + JsonTypes ( const JsonTypes& ); + void _registerType ( JsonObject* ); + JsonObject* _find ( const std::string& tname ); + private: + static JsonTypes* _jsonTypes; + std::set _jsonObjects; + }; + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + class JsonStack { + public: + typedef std::pair Element; + public: + inline JsonStack (); + inline size_t size () const; + template inline void push_back ( const std::string&, T ); + inline void pop_back ( size_t count=1 ); + inline int rhas ( const std::string& ) const; + template inline T as ( const std::string& ) const; + template inline T as ( int ) const; + template inline T getEntity ( unsigned int ) const; + void addEntity ( unsigned int jsonId, Entity* ); + void print ( std::ostream& ) const; + inline JsonStack* setFlags ( unsigned long mask ); + inline JsonStack* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + inline const Element& operator[] ( int index ) const; + private: + unsigned long _flags; + vector _stack; + std::map _entities; + }; + + + inline JsonStack::JsonStack () + : _flags(0), _stack(), _entities() + { } + + template inline void JsonStack::push_back ( const std::string& key, T t ) { + ltrace(51) << "JsonStack::push_back() key:" << key << " t:" << t + << " (" << demangle(typeid(T)) << ")." << endl; + _stack.push_back(std::make_pair(key,boost::any(t))); + } + + inline void JsonStack::pop_back ( size_t count ) + { while (count--) { + if (_stack.empty()) { + std::cerr << "[ERROR] JsonStack::pop_back(): Stack is empty, but " + << (count+1) << " elements remains to pop." << std::endl; + break; + } + ltrace(51) << "| _stack.pop_back() " << _stack.back().first << endl; + _stack.pop_back(); + } + } + + inline const JsonStack::Element& JsonStack::operator[] ( int index ) const + { + if (index < 0) return _stack[_stack.size()+index]; + return _stack[index]; + } + + inline int JsonStack::rhas ( const std::string& key ) const + { + if (_stack.empty()) return 0; + + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" found at index:" + << (i-(int)_stack.size()) << " (i:" << i << ")." << endl; + return i-(int)_stack.size(); + } + if (i == 0) break; + --i; + } while ( true ); + + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" not found (returning index: 0)." << endl; + return 0; + } + + template inline T JsonStack::as ( const std::string& key ) const + { + if (not _stack.empty()) { + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::as() k:" << key + << " t:" << _stack[i].second.type().name() << std::endl; + return boost::any_cast( _stack[i].second ); + } + if (i == 0) break; + --i; + } while ( true ); + + std::cerr << "[ERROR] JsonStack::as(key): No element with key \"" + << key << "\" in stack." << std::endl; + } else { + std::cerr << "[ERROR] JsonStack::as(key): Stack is empty while searching for key \"" + << key << "\"." << std::endl; + } + + return T(); + } + + template inline T JsonStack::as ( int index ) const + { + size_t i = (index >= 0) ? index : (_stack.size()+index); + return boost::any_cast( _stack[i].second ); + } + + template inline T JsonStack::getEntity ( unsigned int id ) const { + std::map::const_iterator it = _entities.find(id); + if (it == _entities.end()) return NULL; + return dynamic_cast((*it).second); + } + + inline size_t JsonStack::size () const { return _stack.size(); } + inline JsonStack* JsonStack::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonStack* JsonStack::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonStack::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + + template + T JsonObject::get ( JsonStack& stack, const std::string& key ) const + { + int index = stack.rhas(key); + if (index == 0) return T();; + + return stack.as( index ); + } + + template inline void JsonObject::update ( JsonStack& stack, T hobject ) + { + stack.pop_back( _attributes.size() ); + stack.push_back( getStackName(), hobject ); + setObject( hobject ); + } + + +// ------------------------------------------------------------------- +// Function : Json Cell parser. + + Cell* jsonCellParse ( std::string filename ); + + +} // Hurricane namespace. + + +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, const C* object, unsigned long flags ) +{ + w->key( key ); + Hurricane::JsonObject* jobject = C::getJsonObject(flags); + jobject->toJson( w, object ); + delete jobject; +} + + +namespace Hurricane { + +// Delayed "void JsonAnyAttribute::toJson()" template definition, because +// it needs the jsonWrite<> template specialisation for "const T*", which can +// be only declared after "JsonObject". + + template + void JsonAnyAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), &(boost::any_cast(object)->*_attribute) ); } + +} // Hurricane namespace. + +#endif // HURRICANE_JSON_READER_H diff --git a/hurricane/src/hurricane/grenier/json/Net.cpp b/hurricane/src/hurricane/grenier/json/Net.cpp new file mode 100644 index 00000000..e2e9c1e9 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/Net.cpp @@ -0,0 +1,1106 @@ +// **************************************************************************************************** +// File: ./Net.cpp +// Authors: R. Escassut +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU +// Lesser General Public License as published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If +// not, see . +// **************************************************************************************************** + +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Plug.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/RoutingPads.h" +#include "hurricane/Pin.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/Error.h" + +namespace Hurricane { + + + +// **************************************************************************************************** +// Filters declaration & implementation +// **************************************************************************************************** + +class Net_IsCellNetFilter : public Filter { +// ******************************************* + + public: Net_IsCellNetFilter() {}; + + public: Net_IsCellNetFilter(const Net_IsCellNetFilter& filter) {}; + + public: Net_IsCellNetFilter& operator=(const Net_IsCellNetFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsCellNetFilter(*this);}; + + public: virtual bool accept(Net* net) const {return !net->isDeepNet();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsCellNetFilter>");}; + +}; + +class Net_IsDeepNetFilter : public Filter { +// ******************************************* + + public: Net_IsDeepNetFilter() {}; + + public: Net_IsDeepNetFilter(const Net_IsDeepNetFilter& filter) {}; + + public: Net_IsDeepNetFilter& operator=(const Net_IsDeepNetFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsDeepNetFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isDeepNet();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsDeepNetFilter>");}; + +}; + +class Net_IsGlobalFilter : public Filter { +// ******************************************* + + public: Net_IsGlobalFilter() {}; + + public: Net_IsGlobalFilter(const Net_IsGlobalFilter& filter) {}; + + public: Net_IsGlobalFilter& operator=(const Net_IsGlobalFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsGlobalFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isGlobal();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsGlobalFilter>");}; + +}; + +class Net_IsExternalFilter : public Filter { +// ********************************************* + + public: Net_IsExternalFilter() {}; + + public: Net_IsExternalFilter(const Net_IsExternalFilter& filter) {}; + + public: Net_IsExternalFilter& operator=(const Net_IsExternalFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsExternalFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isExternal();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsExternalFilter>");}; + +}; + +class Net_IsClockFilter : public Filter { +// ****************************************** + + public: Net_IsClockFilter() {}; + + public: Net_IsClockFilter(const Net_IsClockFilter& filter) {}; + + public: Net_IsClockFilter& operator=(const Net_IsClockFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsClockFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isClock();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsClockFilter>");}; + +}; + +class Net_IsSupplyFilter : public Filter { +// ******************************************* + + public: Net_IsSupplyFilter() {}; + + public: Net_IsSupplyFilter(const Net_IsSupplyFilter& filter) {}; + + public: Net_IsSupplyFilter& operator=(const Net_IsSupplyFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsSupplyFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isSupply();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsSupplyFilter>");}; + +}; + +class Net_IsPowerFilter : public Filter { +// ******************************************* + + public: Net_IsPowerFilter() {}; + + public: Net_IsPowerFilter(const Net_IsPowerFilter& filter) {}; + + public: Net_IsPowerFilter& operator=(const Net_IsPowerFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsPowerFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isPower();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsPowerFilter>");}; + +}; + +class Net_IsGroundFilter : public Filter { +// ******************************************* + + public: Net_IsGroundFilter() {}; + + public: Net_IsGroundFilter(const Net_IsGroundFilter& filter) {}; + + public: Net_IsGroundFilter& operator=(const Net_IsGroundFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsGroundFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isGround();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsGroundFilter>");}; + +}; + + + +// **************************************************************************************************** +// Net_SlavePlugs implementation +// **************************************************************************************************** + +class Net_SlavePlugs : public Collection { +// ******************************************** + +// Types +// ***** + + public: typedef Collection Inherit; + + public: class Locator : public Hurricane::Locator { + // ***************************************************** + + public: typedef Hurricane::Locator Inherit; + + private: const Net* _net; + private: Plug* _plug; + private: InstanceLocator _instanceLocator; + + public: Locator(const Net* net = NULL); + public: Locator(const Locator& locator); + + public: Locator& operator=(const Locator& locator); + + public: virtual Plug* getElement() const; + public: virtual Hurricane::Locator* getClone() const; + + public: virtual bool isValid() const; + + public: virtual void progress(); + + public: virtual string _getString() const; + + }; + +// Attributes +// ********** + + private: const Net* _net; + +// Constructors +// ************ + + public: Net_SlavePlugs(const Net* net = NULL); + public: Net_SlavePlugs(const Net_SlavePlugs& slavePlugs); + +// Operators +// ********* + + public: Net_SlavePlugs& operator=(const Net_SlavePlugs& slavePlugs); + +// Accessors +// ********* + + public: virtual Collection* getClone() const; + public: virtual Hurricane::Locator* getLocator() const; + +// Others +// ****** + + public: virtual string _getString() const; + +}; + + + +// **************************************************************************************************** +// Net implementation +// **************************************************************************************************** + +Net::Net(Cell* cell, const Name& name) +// *********************************** +: Inherit(), + _cell(cell), + _name(name), + _arity(1), + _isGlobal(false), + _isExternal(false), + _isAutomatic(false), + _type(Type::LOGICAL), // default is Type::LOGICAL : no more Type::Undefined - Damien.Dupuis 01/10/2010 + _direction(), + _position(0,0), + _componentSet(), + _rubberSet(), + _nextOfCellNetMap(NULL), + _mainName(this) +{ + if (!_cell) + throw Error("Can't create " + _TName("Net") + " : null cell"); + + if (name.isEmpty()) + throw Error("Can't create " + _TName("Net") + " : empty name"); + + if (_cell->getNet(_name)) + throw Error("Can't create " + _TName("Net ") + getString(_name) + " : already exists"); +} + +Net* Net::create(Cell* cell, const Name& name) +// ******************************************* +{ + Net* net = new Net(cell, name); + + net->_postCreate(); + + return net; +} + +Box Net::getBoundingBox() const +// **************************** +{ + Box boundingBox; + for_each_component(component, getComponents()) { + boundingBox.merge(component->getBoundingBox()); + end_for; + } + return boundingBox; +} + +RoutingPads Net::getRoutingPads() const +// ************************ +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Plugs Net::getPlugs() const +// ************************ +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Pins Net::getPins() const +// ********************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Contacts Net::getContacts() const +// ****************************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Segments Net::getSegments() const +// ****************************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Verticals Net::getVerticals() const +// ******************************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Horizontals Net::getHorizontals() const +// ************************************ +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Pads Net::getPads() const +// ********************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Plugs Net::getSlavePlugs() const +// ***************************** +{ + return Net_SlavePlugs(this); +} + +Plugs Net::getConnectedSlavePlugs() const +// ************************************** +{ + return getSlavePlugs().getSubSet(Plug::getIsConnectedFilter()); +} + +Plugs Net::getUnconnectedSlavePlugs() const +// **************************************** +{ + return getSlavePlugs().getSubSet(Plug::getIsUnconnectedFilter()); +} + +NetFilter Net::getIsCellNetFilter() +// ******************************* +{ + return Net_IsCellNetFilter(); +} + +NetFilter Net::getIsDeepNetFilter() +// ******************************* +{ + return Net_IsDeepNetFilter(); +} + +NetFilter Net::getIsGlobalFilter() +// ******************************* +{ + return Net_IsGlobalFilter(); +} + +NetFilter Net::getIsExternalFilter() +// ********************************* +{ + return Net_IsExternalFilter(); +} + +NetFilter Net::getIsInternalFilter() +// ********************************* +{ + return !Net_IsExternalFilter(); +} + +NetFilter Net::getIsClockFilter() +// ****************************** +{ + return Net_IsClockFilter(); +} + +NetFilter Net::getIsSupplyFilter() +// ******************************* +{ + return Net_IsSupplyFilter(); +} + +NetFilter Net::getIsPowerFilter() +// ******************************* +{ + return Net_IsPowerFilter(); +} + +NetFilter Net::getIsGroundFilter() +// ******************************* +{ + return Net_IsGroundFilter(); +} + +void Net::setName(const Name& name) +// ******************************** +{ + if (name != _name) { + if (name.isEmpty()) + throw Error("Can't change net name : empty name"); + + if (_cell->getNet(name)) + throw Error("Can't change net name : already exists"); + + _cell->_getNetMap()._remove(this); + _name = name; + _cell->_getNetMap()._insert(this); + } +} + +void Net::setArity(const Arity& arity) +// *********************************** +{ + _arity = arity; +} + +void Net::setGlobal(bool isGlobal) +// ******************************* +{ + _isGlobal = isGlobal; +} + +void Net::setExternal(bool isExternal) +// *********************************** +{ + if (isExternal != _isExternal) { + if (!isExternal) { + if (!getConnectedSlavePlugs().isEmpty()) + throw Error("Can't set internal : has connected slave plugs"); + _direction = Direction::UNDEFINED; + } + _isExternal = isExternal; + if (_isExternal) { + UpdateSession::open(); + setPosition(Point(0,0)); + for_each_instance(instance, _cell->getSlaveInstances()) { + Plug::_create(instance, this); + end_for; + } + UpdateSession::close(); + } + } +} + +void Net::setAutomatic(bool isAutomatic) +// ************************************* +{ + _isAutomatic = isAutomatic; +} + +void Net::setType(const Type& type) +// ******************************** +{ + _type = type; +} + +void Net::setPosition(const Point& position) +// ***************************************** +{ + if (_position != position) { + for_each_plug(plug, getSlavePlugs()) { + plug->invalidate(true); + end_for; + } + _position = position; + } +} + +void Net::setDirection(const Direction& direction) +// *********************************************** +{ + _direction = direction; +} + +bool Net::addAlias(const Name& name ) +// ********************************** +{ + if (getCell()->getNet(name)) { + cerr << Warning( "Net::addAlias(): Cannot add alias %s to net %s, already taken." + , getString(name).c_str() + , getString(getName()).c_str() + ) << endl; + return false; + } + + NetAliasName* slave = new NetAliasName ( name ); + _mainName.attach( slave ); + getCell()->_addNetAlias( slave ); + + return true; +} + +bool Net::removeAlias(const Name& name ) +// ************************************* +{ + NetAliasName* slave = _mainName.find( name ); + if (slave) { + slave->detach(); + getCell()->_removeNetAlias( slave ); + return true; + } + return false; +} + +Net* Net::getClone(Cell* clonedCell) +// ********************************* +{ + Net* clonedNet = Net::create( clonedCell, getName() ); + clonedNet->setArity ( getArity() ); + clonedNet->setGlobal ( isGlobal() ); + clonedNet->setExternal ( isExternal() ); + clonedNet->setType ( getType() ); + clonedNet->setDirection( getDirection() ); + + return clonedNet; +} + +void Net::materialize() +// ******************** +{ + for_each_component(component, getComponents()) { + component->materialize(); + end_for; + } + for_each_rubber(rubber, getRubbers()) { + rubber->materialize(); + end_for; + } +} + +void Net::unmaterialize() +// ********************** +{ + for_each_rubber(rubber, getRubbers()) { + rubber->unmaterialize(); + end_for; + } + for_each_component(component, getComponents()) { + component->unmaterialize(); + end_for; + } +} + +static void mergeNets(Net* net1, Net* net2) +// **************************************** +{ + assert(net1); + assert(net2); + + if (net2->getName()[0] != '~') { + if ((net1->getName()[0] == '~') || + (net2->isGlobal() && !net1->isGlobal()) || + (net2->isExternal() && !net1->isExternal())) { + Net* tmpNet = net1; + net1 = net2; + net2 = tmpNet; + } + } + + if (net2->isExternal() && !net1->isExternal()) { + Net* tmpNet = net1; + net1 = net2; + net2 = tmpNet; + } + + net1->merge(net2); +} + +void Net::merge(Net* net) +// ********************** +{ + if (!net) + throw Error("Can't merge net : null net"); + + if (net == this) + throw Error("Can't merge net : itself"); + + if (net->getCell() != _cell) + throw Error("Can't merge net : incompatible net"); + + if (!isExternal() && net->isExternal() && !net->getConnectedSlavePlugs().isEmpty()) + throw Error("Can't merge net : incompatible net"); + + for_each_rubber(rubber, net->getRubbers()) rubber->_setNet(this); end_for; + for_each_component(component, net->getComponents()) component->_setNet(this); end_for; + + if (isExternal() && net->isExternal()) { + for_each_plug(plug, net->getConnectedSlavePlugs()) { + Plug* mainPlug = plug->getInstance()->getPlug(this); + if (mainPlug->isConnected() && (mainPlug->getNet() != plug->getNet())) + mergeNets(mainPlug->getNet(), plug->getNet()); + end_for; + } + for_each_plug(plug, net->getConnectedSlavePlugs()) { + Plug* mainPlug = plug->getInstance()->getPlug(this); + if (!mainPlug->isConnected()) mainPlug->setNet(plug->getNet()); + Hook* masterHook = plug->getBodyHook(); + Hook* nextMasterHook = masterHook->getNextMasterHook(); + if (nextMasterHook != masterHook) { + masterHook->detach(); + mainPlug->getBodyHook()->merge(nextMasterHook); + } + Hooks slaveHooks = masterHook->getSlaveHooks(); + while (!slaveHooks.isEmpty()) { + Hook* slaveHook = slaveHooks.getFirst(); + slaveHook->detach(); + slaveHook->attach(mainPlug->getBodyHook()); + } + plug->_destroy(); + end_for; + } + } + + Name mergedName = net->getName(); + NetAliasName* slaves = NULL; + if (net->_mainName.isAttached()) { + slaves = dynamic_cast( net->_mainName.getNext() ); + net->_mainName.detach(); + } + + if (net->isExternal() and not isExternal()) + setExternal( true ); + net->destroy(); + + if (slaves) _mainName.attach( slaves ); + addAlias( mergedName ); +} + +void Net::_postCreate() +// ******************** +{ + _cell->_getNetMap()._insert(this); + + if (_isExternal) { + for_each_instance(instance, _cell->getSlaveInstances()) { + Plug::_create(instance, this); + end_for; + } + } + + Inherit::_postCreate(); +} + +void Net::_preDestroy() +// ******************* +{ + Inherit::_preDestroy(); + + for_each_plug(slavePlug, getSlavePlugs()) slavePlug->_destroy(); end_for; + + unmaterialize(); + + for_each_rubber(rubber, getRubbers()) rubber->_destroy(); end_for; + + for_each_component(component, getComponents()) { + for_each_hook(hook, component->getHooks()) { + // 15 05 2006 xtof : detach all hooks in rings when + // a net deletion occurs, can't see why master hooks were not detached. + //if (!hook->IsMaster()) hook->detach(); + hook->detach(); + end_for; + } + end_for; + } + + for_each_component(component, getComponents()) { + if (!dynamic_cast(component)) + component->destroy(); + else + ((Plug*)component)->setNet(NULL); + end_for; + } + + _mainName.clear(); + _cell->_getNetMap()._remove(this); +} + +string Net::_getString() const +// *************************** +{ + string s = Inherit::_getString(); + s.insert(s.length() - 1, " " + getString(_name)); + return s; +} + +Record* Net::_getRecord() const +// ********************** +{ + Record* record = Inherit::_getRecord(); + if (record) { + record->add(getSlot("_cell", _cell)); + record->add(getSlot("_name", &_name)); + record->add(getSlot("_arity", &_arity)); + record->add(getSlot("_isGlobal", &_isGlobal)); + record->add(getSlot("_isExternal", &_isExternal)); + record->add(getSlot("_isAutomatic", &_isAutomatic)); + record->add(getSlot("_type", &_type)); + record->add(getSlot("_direction", &_direction)); + record->add(getSlot("_position", &_position)); + record->add(getSlot("_componentsSet", &_componentSet)); + record->add(getSlot("_rubberSet", &_rubberSet)); + record->add(getSlot("_mainName", &_mainName)); + } + return record; +} + +void Net::_toJson( JsonWriter* writer ) const +// ****************************************** +{ + // Inherit::_toJson( writer ); + + // jsonWrite( writer, "_name" , getName() ); + // jsonWrite( writer, "_isGlobal" , isGlobal() ); + // jsonWrite( writer, "_isExternal" , isExternal() ); + // jsonWrite( writer, "_isAutomatic" , isAutomatic() ); + // jsonWrite( writer, "_type" , getType() ); + // jsonWrite( writer, "_direction" , getDirection() ); + // jsonWrite( writer, "+aliases" , getAliases() ); + + // writer->setFlags( JsonWriter::UsePlugReference ); + // jsonWrite( writer, "+componentSet", getComponents() ); + // writer->setFlags( JsonWriter::UsePlugReference ); +} + +JsonObject* Net::getJsonObject(unsigned long flags) +// ************************************************ +{ + return new JsonNet ( flags ); +} + +// **************************************************************************************************** +// Net::Type implementation +// **************************************************************************************************** + +Net::Type::Type(const Code& code) +// ****************************** +: _code(code) +{ } + +Net::Type::Type(const Type& type) +// ****************************** +: _code(type._code) +{ } + +Net::Type::Type(string s) +// ********************** +: _code(UNDEFINED) +{ + if (s == "UNDEFINED") _code = UNDEFINED; + else if (s == "LOGICAL" ) _code = LOGICAL; + else if (s == "CLOCK" ) _code = CLOCK; + else if (s == "POWER" ) _code = POWER; + else if (s == "GROUND" ) _code = GROUND; +} + +Net::Type& Net::Type::operator=(const Type& type) +// ********************************************** +{ + _code = type._code; + return *this; +} + +string Net::Type::_getString() const +// ********************************* +{ + return getString(&_code); +} + +Record* Net::Type::_getRecord() const +// **************************** +{ + Record* record = new Record(getString(this)); + record->add(getSlot("Code", &_code)); + return record; +} + + + +// **************************************************************************************************** +// Net::Direction implementation +// **************************************************************************************************** + +Net::Direction::Direction(const Code& code) +// **************************************** +: _code(code) +{ } + +Net::Direction::Direction(const Direction& direction) +// ************************************************** +: _code(direction._code) +{ } + +Net::Direction::Direction(string s) +// ******************************** +: _code(UNDEFINED) +{ + if (s.size() > 3) { + if (s[0] == 'i') *this |= DirIn; + if (s[0] == 'o') *this |= DirOut; + if (s[0] == 't') *this |= ConnTristate; + if (s[0] == 'w') *this |= ConnWiredOr; + } +} + +Net::Direction& Net::Direction::operator=(const Direction& direction) +// ****************************************************************** +{ + _code = direction._code; + return *this; +} + +Net::Direction& Net::Direction::operator|=(const Direction& direction) +// ****************************************************************** +{ + _code = (Code)((unsigned int)_code | (unsigned int)direction._code); + return *this; +} + +string Net::Direction::_getString() const +// ************************************** +{ + return getString(&_code); +} + +Record* Net::Direction::_getRecord() const +// ********************************* +{ + Record* record = new Record(getString(this)); + record->add(getSlot("Code", &_code)); + return record; +} + + + +// **************************************************************************************************** +// Net::ComponentSet implementation +// **************************************************************************************************** + +Net::ComponentSet::ComponentSet() +// ****************************** +: Inherit() +{ +} + +unsigned Net::ComponentSet::_getHashValue(Component* component) const +// ****************************************************************** +{ + return component->getId() / 8; +} + +Component* Net::ComponentSet::_getNextElement(Component* component) const +// ********************************************************************** +{ + return component->_getNextOfNetComponentSet(); +} + +void Net::ComponentSet::_setNextElement(Component* component, Component* nextComponent) const +// ****************************************************************************************** +{ + component->_setNextOfNetComponentSet(nextComponent); +} + + + +// **************************************************************************************************** +// Net::RubberSet implementation +// **************************************************************************************************** + +Net::RubberSet::RubberSet() +// ************************ +: Inherit() +{ +} + +unsigned Net::RubberSet::_getHashValue(Rubber* rubber) const +// ********************************************************* +{ + return rubber->getId() / 8; +} + +Rubber* Net::RubberSet::_getNextElement(Rubber* rubber) const +// ********************************************************** +{ + return rubber->_getNextOfNetRubberSet(); +} + +void Net::RubberSet::_setNextElement(Rubber* rubber, Rubber* nextRubber) const +// *************************************************************************** +{ + rubber->_setNextOfNetRubberSet(nextRubber); +} + + + +// **************************************************************************************************** +// Net_SlavePlugs implementation +// **************************************************************************************************** + +Net_SlavePlugs::Net_SlavePlugs(const Net* net) +// ******************************************* +: Inherit(), + _net(net) +{ +} + +Net_SlavePlugs::Net_SlavePlugs(const Net_SlavePlugs& slavePlugs) +// ************************************************************* +: Inherit(), + _net(slavePlugs._net) +{ +} + +Net_SlavePlugs& Net_SlavePlugs::operator=(const Net_SlavePlugs& slavePlugs) +// ************************************************************************ +{ + _net = slavePlugs._net; + return *this; +} + +Collection* Net_SlavePlugs::getClone() const +// ************************************************ +{ + return new Net_SlavePlugs(*this); +} + +Locator* Net_SlavePlugs::getLocator() const +// *********************************************** +{ + return new Locator(_net); +} + +string Net_SlavePlugs::_getString() const +// ************************************** +{ + string s = "<" + _TName("Net::SlavePlugs"); + if (_net) s += " " + getString(_net); + s += ">"; + return s; +} + + + +// **************************************************************************************************** +// Net_SlavePlugs::Locator implementation +// **************************************************************************************************** + +Net_SlavePlugs::Locator::Locator(const Net* net) +// ********************************************* +: Inherit(), + _net(net), + _plug(NULL), + _instanceLocator() +{ + if (_net) { + _instanceLocator = _net->getCell()->getSlaveInstances().getLocator(); + while (!_plug && _instanceLocator.isValid()) { + _plug = _instanceLocator.getElement()->getPlug(_net); + _instanceLocator.progress(); + } + } +} + +Net_SlavePlugs::Locator::Locator(const Locator& locator) +// ***************************************************** +: Inherit(), + _net(locator._net), + _plug(locator._plug), + _instanceLocator(locator._instanceLocator) +{ +} + +Net_SlavePlugs::Locator& Net_SlavePlugs::Locator::operator=(const Locator& locator) +// ******************************************************************************** +{ + _net = locator._net; + _plug = locator._plug; + _instanceLocator = locator._instanceLocator; + return *this; +} + +Plug* Net_SlavePlugs::Locator::getElement() const +// ********************************************** +{ + return _plug; +} + +Locator* Net_SlavePlugs::Locator::getClone() const +// ****************************************************** +{ + return new Locator(*this); +} + +bool Net_SlavePlugs::Locator::isValid() const +// ****************************************** +{ + return (_plug != NULL); +} + +void Net_SlavePlugs::Locator::progress() +// ************************************* +{ + if (isValid()) { + _plug = NULL; + while (!_plug && _instanceLocator.isValid()) { + _plug = _instanceLocator.getElement()->getPlug(_net); + _instanceLocator.progress(); + } + } +} + +string Net_SlavePlugs::Locator::_getString() const +// *********************************************** +{ + string s = "<" + _TName("Net::SlavePlugs::Locator"); + if (_net) s += " " + getString(_net); + s += ">"; + return s; +} + + + +// **************************************************************************************************** +// JsonNet implementation +// **************************************************************************************************** + +JsonNet::JsonNet(unsigned long flags) +// ********************************** + : JsonEntity(flags) +{ + addS( "_name" , &Net::_name ); + add ( "_isGlobal" , &Net::_isGlobal ); + add ( "_isExternal" , &Net::_isExternal ); + add ( "_isAutomatic" , &Net::_isAutomatic ); + addS( "_type" , &Net::_type ); + addS( "_direction" , &Net::_direction ); +//addC( "+aliases" , &Net::getAliases ); + add ( "+componentSet", &Net::getComponents ); +} + +string JsonNet::getTypeName() const +// ********************************* +{ return "Net"; } + +JsonNet* JsonNet::clone() const +// **************************** +{ return new JsonNet ( *this ); } + +void JsonNet::toData(JsonStack& stack) +// *********************************** +{ + ltracein(51); + check( stack, "JsonNet::toData" ); + +//unsigned int jsonId = get(stack,"_id"); + Net* net = Net::create ( get(stack,".Cell") , get(stack,"_name") ); + net->setGlobal ( get(stack,"_isGlobal" ) ); + net->setExternal ( get(stack,"_isExternal" ) ); + net->setAutomatic( get(stack,"_isAutomatic") ); + net->setType ( Net::Type (get(stack,"_type")) ); + net->setDirection( Net::Direction(get(stack,"_direction")) ); + + update( stack, net ); + + ltraceout(51); +} + +} // End of Hurricane namespace. + + +// **************************************************************************************************** +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// **************************************************************************************************** diff --git a/hurricane/src/hurricane/grenier/json/Net.h b/hurricane/src/hurricane/grenier/json/Net.h new file mode 100644 index 00000000..e765fb67 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/Net.h @@ -0,0 +1,363 @@ +// **************************************************************************************************** +// File: ./hurricane/Net.h +// Authors: R. Escassut +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU +// Lesser General Public License as published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If +// not, see . +// **************************************************************************************************** + +#ifndef HURRICANE_NET +#define HURRICANE_NET + +#include +#include "hurricane/Entity.h" +#include "hurricane/Nets.h" +#include "hurricane/Component.h" +#include "hurricane/Rubbers.h" +#include "hurricane/Rubber.h" +#include "hurricane/RoutingPads.h" +#include "hurricane/Plugs.h" +#include "hurricane/Pins.h" +#include "hurricane/Contacts.h" +#include "hurricane/Segments.h" +#include "hurricane/Verticals.h" +#include "hurricane/Horizontals.h" +#include "hurricane/Pads.h" +#include "hurricane/IntrusiveSet.h" +#include "hurricane/Path.h" +#include "hurricane/NetAlias.h" + +namespace Hurricane { + + class JsonNet; + +// **************************************************************************************************** +// Net declaration +// **************************************************************************************************** + +class Net : public Entity { +// ********************** + + friend class JsonNet; + +// Types +// ***** + + public: typedef Entity Inherit; + + public: typedef unsigned Arity; + + public: class Type { + // *************** + + public: enum Code {UNDEFINED=0, LOGICAL=1, CLOCK=2, POWER=3, GROUND=4}; + + private: Code _code; + + public: Type(const Code& code = UNDEFINED); + public: Type(const Type& type); + public: Type(string); + + public: Type& operator=(const Type& type); + + public: operator const Code&() const {return _code;}; + + public: const Code& getCode() const {return _code;}; + + public: string _getTypeName() const { return _TName("Net::type"); }; + public: string _getString() const; + public: Record* _getRecord() const; + + }; + + public: class Direction { + // ******************** + + public: enum Code { DirIn = 0x0001 + , DirOut = 0x0002 + , DirUndefined = 0x0000 + , ConnTristate = 0x0100 + , ConnWiredOr = 0x0200 + , UNDEFINED = DirUndefined + , IN = DirIn + , OUT = DirOut + , INOUT = DirIn | DirOut + , TRISTATE = DirOut | ConnTristate + , TRANSCV = DirIn | DirOut | ConnTristate + , WOR_OUT = DirOut | ConnWiredOr + , WOR_INOUT = DirIn | DirOut | ConnWiredOr + , DirMask = DirIn | DirOut | DirUndefined + }; + + private: Code _code; + + public: Direction(const Code& code = UNDEFINED); + public: Direction(const Direction& direction); + public: Direction(string); + + public: Direction& operator =(const Direction& direction); + public: Direction& operator|=(const Direction& direction); + + public: operator const Code&() const {return _code;}; + + public: const Code& getCode() const {return _code;}; + + public: string _getTypeName() const { return _TName("Net::Direction"); }; + public: string _getString() const; + public: Record* _getRecord() const; + + }; + + class ComponentSet : public IntrusiveSet { + // ************************************************ + + public: typedef IntrusiveSet Inherit; + + public: ComponentSet(); + + public: virtual unsigned _getHashValue(Component* component) const; + public: virtual Component* _getNextElement(Component* component) const; + public: virtual void _setNextElement(Component* component, Component* nextComponent) const; + + }; + + class RubberSet : public IntrusiveSet { + // ****************************************** + + public: typedef IntrusiveSet Inherit; + + public: RubberSet(); + + public: virtual unsigned _getHashValue(Rubber* rubber) const; + public: virtual Rubber* _getNextElement(Rubber* rubber) const; + public: virtual void _setNextElement(Rubber* rubber, Rubber* nextRubber) const; + + }; + +// Attributes +// ********** + + private: Cell* _cell; + private: Name _name; + private: Arity _arity; + private: bool _isGlobal; + private: bool _isExternal; + private: bool _isAutomatic; + private: Type _type; + private: Direction _direction; + private: Point _position; + private: ComponentSet _componentSet; + private: RubberSet _rubberSet; + private: Net* _nextOfCellNetMap; + private: NetMainName _mainName; + +// Constructors +// ************ + + protected: Net(Cell* cell, const Name& name); + + public: static Net* create(Cell* cell, const Name& name); + +// Accessors +// ********* + + public: virtual Cell* getCell() const {return _cell;}; + public: virtual Box getBoundingBox() const; + public: const Name& getName() const {return _name;}; + public: const NetMainName* getMainName() const { return &_mainName; } + public: const Arity& getArity() const {return _arity;}; + public: const Type& getType() const {return _type;}; + public: const Direction& getDirection() const {return _direction;}; + public: const Point& getPosition() const {return _position;}; + public: const DbU::Unit& getX() const {return _position.getX();}; + public: const DbU::Unit& getY() const {return _position.getY();}; + public: Components getComponents() const {return _componentSet.getElements();}; + public: Rubbers getRubbers() const {return _rubberSet.getElements();}; + public: RoutingPads getRoutingPads() const; + public: Plugs getPlugs() const; + public: Pins getPins() const; + public: Contacts getContacts() const; + public: Segments getSegments() const; + public: Verticals getVerticals() const; + public: Horizontals getHorizontals() const; + public: Pads getPads() const; + public: Plugs getSlavePlugs() const; + public: Plugs getConnectedSlavePlugs() const; + public: Plugs getUnconnectedSlavePlugs() const; + public: Aliases getAliases() const { return new AliasList(this); }; + +// Filters +// ******* + + public: static NetFilter getIsCellNetFilter(); + public: static NetFilter getIsDeepNetFilter(); + public: static NetFilter getIsGlobalFilter(); + public: static NetFilter getIsExternalFilter(); + public: static NetFilter getIsInternalFilter(); + public: static NetFilter getIsClockFilter(); + public: static NetFilter getIsSupplyFilter(); + public: static NetFilter getIsPowerFilter(); + public: static NetFilter getIsGroundFilter(); + +// Predicates +// ********** + + public: virtual bool isDeepNet () const {return false;}; + public: bool isGlobal () const {return _isGlobal;}; + public: bool isExternal () const {return _isExternal;}; + public: bool isAutomatic() const {return _isAutomatic;}; + public: bool isLogical () const {return (_type == Type::LOGICAL);}; + public: bool isClock () const {return (_type == Type::CLOCK);}; + public: bool isPower () const {return (_type == Type::POWER);}; + public: bool isGround () const {return (_type == Type::GROUND);}; + public: bool isSupply () const {return (isPower() || isGround());}; + +// Updators +// ******** + + public: void setName(const Name& name); + public: void setArity(const Arity& arity); + public: void setGlobal(bool isGlobal); + public: void setExternal(bool isExternal); + public: void setAutomatic(bool isAutomatic); + public: void setType(const Type& type); + public: void setDirection(const Direction& direction); + public: void setPosition(const Point& position); + public: void materialize(); + public: void unmaterialize(); + public: bool addAlias(const Name& name); + public: bool removeAlias(const Name& name); + public: void merge(Net* net); + public: Net* getClone(Cell* cloneCell); + +// Others +// ****** + + protected: virtual void _postCreate(); + protected: virtual void _preDestroy(); + + public: virtual void _toJson ( JsonWriter* ) const; + public: static JsonObject* getJsonObject(unsigned long flags); + public: virtual string _getTypeName() const {return _TName("Net");}; + public: virtual string _getString() const; + public: virtual Record* _getRecord() const; + public: NetMainName& _getMainName() { return _mainName; } + public: ComponentSet& _getComponentSet() {return _componentSet;}; + public: RubberSet& _getRubberSet() {return _rubberSet;}; + public: Net* _getNextOfCellNetMap() const {return _nextOfCellNetMap;}; + + public: void _setNextOfCellNetMap(Net* net) {_nextOfCellNetMap = net;}; + +}; + +class JsonNet : public JsonEntity { +// ******************************** + + public: JsonNet(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonNet* clone() const; + public: virtual void toData(JsonStack&); +}; + +} // End of Hurricane namespace. + + +// ------------------------------------------------------------------- +// Inspector Support for : Net::Type::Code*". + +template<> +inline std::string getString + ( const Hurricane::Net::Type::Code* object ) + { + switch ( *object ) { + case Hurricane::Net::Type::UNDEFINED: return "UNDEFINED"; + case Hurricane::Net::Type::LOGICAL: return "LOGICAL"; + case Hurricane::Net::Type::CLOCK: return "CLOCK"; + case Hurricane::Net::Type::POWER: return "POWER"; + case Hurricane::Net::Type::GROUND: return "GROUND"; + } + return "ABNORMAL"; + } + +template<> +inline Hurricane::Record* getRecord + ( const Hurricane::Net::Type::Code* object ) + { + Hurricane::Record* record = new Hurricane::Record(getString(object)); + record->add(getSlot("Code", (unsigned int*)object)); + return record; + } + + +// ------------------------------------------------------------------- +// Inspector Support for : "const Net::Direction::Code*". + +template<> +inline std::string getString + ( const Hurricane::Net::Direction::Code* object ) + { + std::ostringstream s; + s << (((*object) & Hurricane::Net::Direction::DirIn ) ? 'i' : '-'); + s << (((*object) & Hurricane::Net::Direction::DirOut ) ? 'o' : '-'); + s << (((*object) & Hurricane::Net::Direction::ConnTristate) ? 't' : '-'); + s << (((*object) & Hurricane::Net::Direction::ConnWiredOr ) ? 'w' : '-'); + + switch ( (int)*object ) { + case Hurricane::Net::Direction::UNDEFINED: s << " (UNDEFINED)"; break; + case Hurricane::Net::Direction::IN: s << " (IN)"; break; + case Hurricane::Net::Direction::OUT: s << " (OUT)"; break; + case Hurricane::Net::Direction::INOUT: s << " (INOUT)"; break; + case Hurricane::Net::Direction::TRISTATE: s << " (TRISTATE)"; break; + case Hurricane::Net::Direction::TRANSCV: s << " (TRANSCV)"; break; + case Hurricane::Net::Direction::WOR_OUT: s << " (WOR_OUT)"; break; + case Hurricane::Net::Direction::WOR_INOUT: s << " (WOR_INOUT)"; break; + } + return s.str(); + } + +template<> +inline Hurricane::Record* getRecord + ( const Hurricane::Net::Direction::Code* object ) + { + Hurricane::Record* record = new Hurricane::Record(getString(object)); + record->add(getSlot("Code", (unsigned int*)object)); + return record; + } + + +INSPECTOR_P_SUPPORT(Hurricane::Net); +INSPECTOR_P_SUPPORT(Hurricane::Net::ComponentSet); +INSPECTOR_P_SUPPORT(Hurricane::Net::RubberSet); +INSPECTOR_PV_SUPPORT(Hurricane::Net::Type); +INSPECTOR_PV_SUPPORT(Hurricane::Net::Direction); +IOSTREAM_POINTER_SUPPORT(Hurricane::Net::Type::Code); +IOSTREAM_VALUE_SUPPORT(Hurricane::Net::Type::Code); +IOSTREAM_POINTER_SUPPORT(Hurricane::Net::Direction::Code); +IOSTREAM_VALUE_SUPPORT(Hurricane::Net::Direction::Code); + + +namespace Hurricane { + +// Force SlotTemplate<> expansion on Net* type. +// Because sometimes it didn't happens (?). + const SlotTemplate dummyNetSlot ( string("dummyNetSlot"), NULL ); + +} + +#endif // HURRICANE_NET + + +// **************************************************************************************************** +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// **************************************************************************************************** diff --git a/hurricane/src/hurricane/hurricane/Box.h b/hurricane/src/hurricane/hurricane/Box.h index e8b18f5f..37c37337 100644 --- a/hurricane/src/hurricane/hurricane/Box.h +++ b/hurricane/src/hurricane/hurricane/Box.h @@ -24,8 +24,6 @@ namespace Hurricane { - - // **************************************************************************************************** // Box declaration // **************************************************************************************************** @@ -36,7 +34,6 @@ class Box { // Attributes // ********** - private: DbU::Unit _xMin; private: DbU::Unit _yMin; private: DbU::Unit _xMax; @@ -125,10 +122,20 @@ class Box { public: string _getTypeName() const { return _TName("Box"); }; public: string _getString() const; public: Record* _getRecord() const; + public: void toJson(JsonWriter*) const; }; +class JsonBox : public JsonObject { +// ******************************** + + public: JsonBox(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonBox* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 0ea136a4..55107f02 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -23,6 +23,7 @@ #include #include "hurricane/Flags.h" #include "hurricane/Observer.h" +#include "hurricane/Signature.h" #include "hurricane/Relation.h" #include "hurricane/Pathes.h" #include "hurricane/Entity.h" @@ -54,7 +55,6 @@ namespace Hurricane { class Library; class BasicLayer; - typedef multimap SlaveEntityMap; @@ -302,6 +302,9 @@ class Cell : public Entity { public: void _changeQuadTree(Cell*); public: void _setShuntedPath(Path path) { _shuntedPath=path; } + public: virtual void _toJson(JsonWriter*) const; + public: virtual void _toJsonCollections(JsonWriter*) const; + // Constructors // ************ @@ -313,9 +316,11 @@ class Cell : public Entity { public: virtual Cell* getCell() const {return (Cell*)this;}; public: virtual Box getBoundingBox() const; public: Library* getLibrary() const {return _library;}; + public: string getHierarchicalName() const; public: const Name& getName() const {return _name;}; public: const Flags& getFlags() const { return _flags; } public: Path getShuntedPath() const { return _shuntedPath; } + public: Entity* getEntity(const Signature&) const; public: Instance* getInstance(const Name& name) const {return _instanceMap.getElement(name);}; public: Instances getInstances() const {return _instanceMap.getElements();}; public: Instances getPlacedInstances() const; @@ -441,6 +446,15 @@ inline Cell::ClonedSet::ClonedSet ( const ClonedSet& other ) { } +class JsonCell : public JsonEntity { +// ********************************* + + public: JsonCell(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonCell* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Collection.h b/hurricane/src/hurricane/hurricane/Collection.h index 0064f0ab..805d5e68 100644 --- a/hurricane/src/hurricane/hurricane/Collection.h +++ b/hurricane/src/hurricane/hurricane/Collection.h @@ -27,6 +27,7 @@ namespace Hurricane { template class GenericCollection; template class SubTypeCollection; +template class NotSubTypeCollection; template class SubSetCollection; @@ -113,6 +114,12 @@ template class Collection { return getSubSet().getSubSet(filter); } + public: template GenericCollection getNotSubSet() const + // **************************************************************************** + { + return NotSubTypeCollection(this); + } + // Predicates // ********** @@ -627,6 +634,171 @@ template class SubTypeCollection : public Collection< }; +// **************************************************************************************************** +// NotSubTypeCollection declaration +// **************************************************************************************************** + +template class NotSubTypeCollection : public Collection { +// ****************************************************************************************** + +// Types +// ***** + + public: typedef Collection Inherit; + + public: class Locator : public Hurricane::Locator { + // ******************************************************* + + // Types + // ***** + + public: typedef Hurricane::Locator Inherit; + + // Attributes + // ********** + + private: GenericLocator _locator; + + // Constructors + // ************ + + public: Locator(const GenericCollection& collection) + // ******************************************************** + : Inherit(), + _locator(collection.getLocator()) + { + while (_locator.isValid() && dynamic_cast(_locator.getElement())) + _locator.progress(); + } + + public: Locator(const GenericLocator& genericLocator) + // ******************************************************** + : Inherit(), + _locator(genericLocator.getClone()) + { + while (_locator.isValid() && !dynamic_cast(_locator.getElement())) + _locator.progress(); + } + + // Accessors + // ********* + + public: virtual SubType getElement() const + // *************************************** + { + return (_locator.isValid()) ? (SubType)_locator.getElement() : SubType(); + } + + public: virtual Hurricane::Locator* getClone() const + // ********************************************************** + { + return new Locator(_locator); + } + + public: virtual Hurricane::Locator* getLocator() // 21-10-03 + // ************************************************* + { + return dynamic_cast*> ( + _locator.getLocator()->getLocator() ); + } + + + // Predicates + // ********** + + public: virtual bool isValid() const + // ********************************* + { + return _locator.isValid(); + } + + // Updators + // ******** + + public: virtual void progress() + // **************************** + { + if (_locator.isValid()) { + do { + _locator.progress(); + } while (_locator.isValid() && !dynamic_cast(_locator.getElement())); + } + } + + }; + +// Attributes +// ********** + + private: GenericCollection _collection; + +// Constructors +// ************ + + public: NotSubTypeCollection() + // ******************** + : Inherit(), + _collection() + { + } + + public: NotSubTypeCollection(const Collection* collection) + // ********************************************************** + : Inherit(), + _collection(collection->getClone()) + { + } + + public: NotSubTypeCollection(const GenericCollection& collection) + // ***************************************************************** + : Inherit(), + _collection(collection) + { + } + + public: NotSubTypeCollection(const NotSubTypeCollection& subTypeCollection) + // ****************************************************************** + : Inherit(), + _collection(subTypeCollection._collection) + { + } + +// Operators +// ********* + + public: NotSubTypeCollection& operator=(const NotSubTypeCollection& subTypeCollection) + // ***************************************************************************** + { + _collection = subTypeCollection._collection; + return *this; + } + +// Accessors +// ********* + + public: virtual Collection* getClone() const + // ************************************************** + { + return new NotSubTypeCollection(_collection); + } + + public: virtual Hurricane::Locator* getLocator() const + // ************************************************************ + { + return new Locator(_collection); + } + +// Accessors +// ********* + + public: virtual string _getString() const + // ************************************** + { + return "<" + _TName("NotSubTypeCollection") + " " + getString(_collection) + ">"; + } + +}; + // **************************************************************************************************** // SubSetCollection implementation @@ -909,7 +1081,6 @@ inline ForEachIterator& ForEachIterator::operator++ (int) for ( ForEachIterator iterator(collection); iterator.isValid() ; iterator++ ) - } // End of Hurricane namespace. @@ -932,6 +1103,24 @@ template inline Hurricane::Record* getRecord ( const Hurricane::C { return collection->_getRecord(); } +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::GenericCollection collection ) +{ + if (Hurricane::inltrace(50)) + std::cerr << Hurricane::tab + << "jsonWrite< GenericCollection<" << Hurricane::demangle(typeid(Type).name()) + << "> >(w,key,coll)" << " key:\"" << key << "\"" << std::endl; + Hurricane::ltracein(50); + + w->key( key ); + w->startArray(); + for ( Type element : collection ) jsonWrite( w, element ); + w->endArray(); + + Hurricane::ltraceout(50); +} + + #include "hurricane/MultisetCollection.h" #include "hurricane/SetCollection.h" #include "hurricane/MapCollection.h" diff --git a/hurricane/src/hurricane/hurricane/Commons.h b/hurricane/src/hurricane/hurricane/Commons.h index 9825b625..7ccabc15 100644 --- a/hurricane/src/hurricane/hurricane/Commons.h +++ b/hurricane/src/hurricane/hurricane/Commons.h @@ -740,6 +740,8 @@ inline Hurricane::Record* getRecord ( const std::multiset* s ) #include "hurricane/Slot.h" #include "hurricane/Tabulation.h" +#include "hurricane/JsonWriter.h" +#include "hurricane/JsonReader.h" #endif // HURRICANE_COMMONS_H diff --git a/hurricane/src/hurricane/hurricane/Component.h b/hurricane/src/hurricane/hurricane/Component.h index 232b1e1d..b330fd21 100644 --- a/hurricane/src/hurricane/hurricane/Component.h +++ b/hurricane/src/hurricane/hurricane/Component.h @@ -33,7 +33,6 @@ class Rubber; class Layer; - // **************************************************************************************************** // Component declaration // **************************************************************************************************** @@ -59,8 +58,9 @@ class Component : public Go { public: virtual bool isMaster() const {return true;}; - public: virtual string _getTypeName() const { return _TName("Component::BodyHook"); }; + public: virtual string _getTypeName() const { return "Component::BodyHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; @@ -101,6 +101,7 @@ class Component : public Go { public: virtual void materialize(); public: virtual void unmaterialize(); public: virtual void invalidate(bool propagateFlag = true); + public: virtual void forceId(unsigned int id); // Filters // ******* @@ -114,6 +115,8 @@ class Component : public Go { protected: virtual void _preDestroy(); + public: virtual void _toJson ( JsonWriter* ) const; + public: virtual void _toJsonSignature(JsonWriter*) const; public: virtual string _getString() const; public: virtual Record* _getRecord() const; public: Component* _getNextOfNetComponentSet() const {return _nextOfNetComponentSet;}; @@ -128,6 +131,12 @@ class Component : public Go { double getArea ( Component* component ); +class JsonComponent : public JsonEntity { +// ************************************ + + public: JsonComponent(unsigned long flags); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Contact.h b/hurricane/src/hurricane/hurricane/Contact.h index 942c5b29..93b91c44 100644 --- a/hurricane/src/hurricane/hurricane/Contact.h +++ b/hurricane/src/hurricane/hurricane/Contact.h @@ -26,7 +26,6 @@ namespace Hurricane { - // **************************************************************************************************** // Contact declaration // **************************************************************************************************** @@ -52,8 +51,9 @@ class Contact : public Component { public: virtual bool isMaster() const {return false;}; - public: virtual string _getTypeName() const { return _TName("Contact::AnchorHook"); }; + public: virtual string _getTypeName() const { return "Contact::AnchorHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; // Attributes @@ -141,6 +141,7 @@ class Contact : public Component { protected: virtual void _preDestroy(); + public: virtual void _toJson(JsonWriter*) const; public: virtual string _getTypeName() const {return _TName("Contact");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -148,6 +149,15 @@ class Contact : public Component { }; +class JsonContact : public JsonComponent { +// *************************************** + + public: JsonContact(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonContact* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/DBo.h b/hurricane/src/hurricane/hurricane/DBo.h index 197ae473..44714b2b 100644 --- a/hurricane/src/hurricane/hurricane/DBo.h +++ b/hurricane/src/hurricane/hurricane/DBo.h @@ -1,4 +1,3 @@ - // -*- C++ -*- // // Copyright (c) BULL S.A. 2000-2015, All Rights Reserved @@ -19,12 +18,7 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -32,14 +26,11 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./hurricane/DBo.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __HURRICANE_DBO__ -#define __HURRICANE_DBO__ +#ifndef HURRICANE_DBO_H +#define HURRICANE_DBO_H #include "hurricane/DBos.h" #include "hurricane/Name.h" @@ -52,40 +43,39 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "Hurricane::DBo". - class DBo { - public: - // Methods. - virtual void destroy(); - inline set& _getPropertySet (); - void _onDestroyed ( Property* property ); - Property* getProperty ( const Name& ) const; - Properties getProperties () const; - inline bool hasProperty () const; - void put ( Property* ); - void remove ( Property* ); - void removeProperty ( const Name& ); - void clearProperties (); - // Hurricane Managment. - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; - - private: - // Internal: Attributes. - mutable set _propertySet; - - protected: - // Internal: Constructors & Destructors. - DBo (); - virtual ~DBo (); - virtual void _postCreate (); - virtual void _preDestroy (); - private: - // Forbidden: Copies. - DBo ( const DBo& ); - DBo& operator= ( const DBo& ); + virtual void destroy (); + inline set& _getPropertySet (); + void _onDestroyed ( Property* property ); + Property* getProperty ( const Name& ) const; + Properties getProperties () const; + inline bool hasProperty () const; + void put ( Property* ); + void remove ( Property* ); + void removeProperty ( const Name& ); + void clearProperties (); + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + virtual void _toJson ( JsonWriter* ) const; + virtual void _toJsonCollections ( JsonWriter* ) const; + virtual void _toJsonSignature ( JsonWriter* ) const; + void toJson ( JsonWriter* ) const; + void toJsonSignature ( JsonWriter* ) const; + + private: + mutable set _propertySet; + + protected: + DBo (); + virtual ~DBo (); + virtual void _postCreate (); + virtual void _preDestroy (); + + private: + DBo ( const DBo& ); + DBo& operator= ( const DBo& ); }; @@ -94,10 +84,17 @@ namespace Hurricane { inline bool DBo::hasProperty () const { return !_propertySet.empty(); } -} // End of Hurricane namespace. +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + class JsonDBo : public JsonObject { + public: + JsonDBo ( unsigned int flags ); +}; + + +} // Hurricane namespace. INSPECTOR_P_SUPPORT(Hurricane::DBo); - -#endif // __HURRICANE_DBO__ +#endif // HURRICANE_DBO_H diff --git a/hurricane/src/hurricane/hurricane/DataBase.h b/hurricane/src/hurricane/hurricane/DataBase.h index 81054082..efd1bc22 100644 --- a/hurricane/src/hurricane/hurricane/DataBase.h +++ b/hurricane/src/hurricane/hurricane/DataBase.h @@ -20,11 +20,13 @@ #ifndef HURRICANE_DATA_BASE #define HURRICANE_DATA_BASE +#include #include "hurricane/DBo.h" #include "hurricane/DbU.h" namespace Hurricane { +class Cell; class Library; class Technology; @@ -37,8 +39,6 @@ class Technology; class DataBase : public DBo { // ************************ -# if !defined(__DOXYGEN_PROCESSOR__) - // Types // ***** @@ -50,6 +50,7 @@ class DataBase : public DBo { private: static DataBase* _db; private: Technology* _technology; private: Library* _rootLibrary; + private: function _cellLoader; // Constructors // ************ @@ -69,8 +70,7 @@ class DataBase : public DBo { public: void _setTechnology(Technology* technology) {_technology = technology;}; public: void _setRootLibrary(Library* rootLibrary) {_rootLibrary = rootLibrary;}; - -# endif + public: void _setCellLoader(function loader) { _cellLoader=loader; }; public: static DataBase* create(); @@ -79,6 +79,8 @@ class DataBase : public DBo { public: Technology* getTechnology() const {return _technology;}; public: Library* getRootLibrary() const {return _rootLibrary;}; + public: Library* getLibrary(string) const; + public: Cell* getCell(string) const; public: static DataBase* getDB(); }; diff --git a/hurricane/src/hurricane/hurricane/DbU.h b/hurricane/src/hurricane/hurricane/DbU.h index 11b03828..18a19eb1 100644 --- a/hurricane/src/hurricane/hurricane/DbU.h +++ b/hurricane/src/hurricane/hurricane/DbU.h @@ -180,4 +180,8 @@ namespace Hurricane { } // End of Hurricane namespace. +// inline void jsonWriteDbU ( JsonWriter* w, const std::string& key, long* value ) +// { w->key( key ); w->write( value ); } + + #endif // HURRICANE_DBU_H diff --git a/hurricane/src/hurricane/hurricane/DeepNet.h b/hurricane/src/hurricane/hurricane/DeepNet.h index e41c0d0a..6ff462d3 100644 --- a/hurricane/src/hurricane/hurricane/DeepNet.h +++ b/hurricane/src/hurricane/hurricane/DeepNet.h @@ -36,45 +36,47 @@ #include "hurricane/HyperNet.h" #include "hurricane/Occurrence.h" - namespace Hurricane { - class DeepNet : public Net { - // Attributes. +// ------------------------------------------------------------------- +// Class : "DeepNet". + + class DeepNet : public Net { + public: + typedef Net Inherit; + public: + static DeepNet* create ( HyperNet& hyperNet ); + inline Occurrence getRootNetOccurrence () const; + virtual bool isDeepNet () const { return true; }; + size_t _createRoutingPads ( unsigned int flags=0 ); + virtual Record* _getRecord () const; + virtual string _getTypeName () const { return "DeepNet"; }; + virtual void _toJson ( JsonWriter* ) const; + protected: + DeepNet ( Occurrence& netOccurrence ); protected: Occurrence _netOccurrence; - // Constructors. - protected: - DeepNet ( Occurrence& netOccurrence ); + }; - // Inspector Management. + + inline Occurrence DeepNet::getRootNetOccurrence() const { return _netOccurrence; } + + Net* getDeepNet(HyperNet& hyperNet); + + +// ------------------------------------------------------------------- +// Class : "JsonDeepNet". + + class JsonDeepNet : public JsonNet { public: - virtual Record* _getRecord () const; - virtual string _getTypeName() const { return "DeepNet"; }; - - // Constructors. - public: - static DeepNet* create ( HyperNet& hyperNet ); - - // Accessors. - public: - inline Occurrence getRootNetOccurrence () const; - - // Predicates. - public: - virtual bool isDeepNet () const { return true; }; - - // Internal Modifiers. - public: - size_t _createRoutingPads ( unsigned int flags=0 ); - -}; - -inline Occurrence DeepNet::getRootNetOccurrence() const { return _netOccurrence; } - -Net* getDeepNet(HyperNet& hyperNet); + JsonDeepNet ( unsigned long flags ); + virtual ~JsonDeepNet (); + virtual string getTypeName () const; + virtual JsonDeepNet* clone ( unsigned long ) const; + virtual void toData ( JsonStack&); + }; } // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/DesignBlob.h b/hurricane/src/hurricane/hurricane/DesignBlob.h new file mode 100644 index 00000000..c5c9adaf --- /dev/null +++ b/hurricane/src/hurricane/hurricane/DesignBlob.h @@ -0,0 +1,60 @@ +// -*- mode: C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/DesignBlob.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_DESIGN_BLOB_H +#define HURRICANE_DESIGN_BLOB_H + +#include "hurricane/Commons.h" + + +namespace Hurricane { + + class Cell; + +// ------------------------------------------------------------------- +// Classes : "DesignBlob". + + class DesignBlob { + public: + inline DesignBlob ( Cell* ); + inline Cell* getTopCell () const; + void toJson ( JsonWriter* ) const; + inline std::string _getTypeName () const; + private: + Cell* _topCell; + }; + + + inline DesignBlob::DesignBlob ( Cell* topCell ) : _topCell(topCell) { } + inline Cell* DesignBlob::getTopCell () const { return _topCell; } + inline std::string DesignBlob::_getTypeName () const { return "DesignBlob"; } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDesignBlob". + + class JsonDesignBlob : public JsonObject { + public: + JsonDesignBlob ( unsigned long flags ); + virtual std::string getTypeName () const; + virtual JsonDesignBlob* clone ( unsigned long ) const; + virtual void toData ( JsonStack& ); +}; + + +} // Hurricane namespace. + +#endif diff --git a/hurricane/src/hurricane/hurricane/Entity.h b/hurricane/src/hurricane/hurricane/Entity.h index b3c5679f..2fe01aec 100644 --- a/hurricane/src/hurricane/hurricane/Entity.h +++ b/hurricane/src/hurricane/hurricane/Entity.h @@ -35,26 +35,38 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "Hurricane::Entity". - class Entity : public DBo { public: typedef DBo Inherit; public: - static unsigned int getIdCounter (); + enum Flags { ForcedIdMode = (1<<0) + , NextIdSet = (1<<1) + }; public: - inline unsigned int getId () const; - virtual Cell* getCell () const = 0; - virtual Box getBoundingBox() const = 0; - virtual string _getString () const; - virtual Record* _getRecord () const; - Quark* _getQuark ( SharedPath* sharedPath = NULL ) const; - protected: - Entity (); - virtual void _preDestroy (); + static unsigned int getIdCounter (); + unsigned int getNextId (); + static void setNextId ( unsigned int ); + static bool inForcedIdMode (); + static void enableForcedIdMode (); + static void disableForcedIdMode (); + public: + inline unsigned int getId () const; + virtual Cell* getCell () const = 0; + virtual Box getBoundingBox () const = 0; + void setId ( unsigned int ); + virtual void _toJson ( JsonWriter* ) const; + virtual string _getString () const; + virtual Record* _getRecord () const; + Quark* _getQuark ( SharedPath* sharedPath = NULL ) const; + protected: + Entity (); + virtual void _preDestroy (); private: - static unsigned int _idCounter; - unsigned int _id; + static unsigned long _flags; + static unsigned int _nextId; + static unsigned int _idCounter; + unsigned int _id; public: struct CompareById : public std::binary_function { @@ -68,6 +80,24 @@ namespace Hurricane { { return ((lhs)?lhs->getId():0) < ((rhs)?rhs->getId():0); } +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonEntity". + + class JsonEntity : public JsonDBo { + public: + JsonEntity ( unsigned long flags ); + template inline void update ( JsonStack&, T ); +}; + + + template inline void JsonEntity::update ( JsonStack& stack, T hobject ) + { + unsigned int jsonId = get(stack,"_id"); + + JsonObject::update( stack, hobject ); + stack.addEntity( jsonId, hobject ); + } + } // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Hook.h b/hurricane/src/hurricane/hurricane/Hook.h index 8cc8de2d..c9f1ce57 100644 --- a/hurricane/src/hurricane/hurricane/Hook.h +++ b/hurricane/src/hurricane/hurricane/Hook.h @@ -35,9 +35,12 @@ class Component; class Hook { // ********* + typedef Hook* (*compToHook_t)(Component*); + // Attributes // ********** + private: static map _compToHookMap; private: Hook* _nextHook; // Constructors @@ -95,13 +98,16 @@ class Hook { // Others // ****** + public: static void addCompToHook(const string&, compToHook_t ); + public: static Hook* compToHook(const string& tname, Component* ); + public: string toJson() const; + public: virtual string _getTypeName() const = 0; public: virtual string _getString() const = 0; public: virtual Record* _getRecord() const; }; - } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Horizontal.h b/hurricane/src/hurricane/hurricane/Horizontal.h index d2e3c1d0..2a2cdcd7 100644 --- a/hurricane/src/hurricane/hurricane/Horizontal.h +++ b/hurricane/src/hurricane/hurricane/Horizontal.h @@ -104,6 +104,8 @@ class Horizontal : public Segment { // Others // ****** + public: virtual void _toJson(JsonWriter*) const; + public: static JsonObject* getJsonObject(unsigned long flags); public: virtual string _getTypeName() const {return _TName("Horizontal");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -111,6 +113,15 @@ class Horizontal : public Segment { }; +class JsonHorizontal : public JsonSegment { +// **************************************** + + public: JsonHorizontal(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonHorizontal* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Instance.h b/hurricane/src/hurricane/hurricane/Instance.h index 538714b7..19cab0d0 100644 --- a/hurricane/src/hurricane/hurricane/Instance.h +++ b/hurricane/src/hurricane/hurricane/Instance.h @@ -51,6 +51,7 @@ class Instance : public Go { public: PlacementStatus(const Code& code = UNPLACED); public: PlacementStatus(const PlacementStatus& placementstatus); + public: PlacementStatus(string); public: PlacementStatus& operator=(const PlacementStatus& placementstatus); @@ -178,6 +179,8 @@ class Instance : public Go { public: virtual string _getTypeName() const {return _TName("Instance");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; + public: virtual void _toJson(JsonWriter*) const; + public: virtual void _toJsonCollections(JsonWriter*) const; public: PlugMap& _getPlugMap() {return _plugMap;}; public: SharedPath* _getSharedPath(const SharedPath* tailSharedPath) const {return _sharedPathMap.getElement(tailSharedPath);} public: SharedPathes _getSharedPathes() const {return _sharedPathMap.getElements();}; @@ -191,6 +194,15 @@ class Instance : public Go { }; +class JsonInstance : public JsonEntity { +// ************************************* + + public: JsonInstance(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonInstance* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. @@ -245,6 +257,11 @@ INSPECTOR_P_SUPPORT(Hurricane::Instance::PlacementStatus); INSPECTOR_P_SUPPORT(Hurricane::Instance::PlugMap); INSPECTOR_P_SUPPORT(Hurricane::Instance::SharedPathMap); +inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane::Instance::PlacementStatus& status ) +{ + w->key( key ); + w->write( getString(status.getCode()) ); +} #endif // HURRICANE_INSTANCE diff --git a/hurricane/src/hurricane/hurricane/Interval.h b/hurricane/src/hurricane/hurricane/Interval.h index e62c2841..7ee2f263 100644 --- a/hurricane/src/hurricane/hurricane/Interval.h +++ b/hurricane/src/hurricane/hurricane/Interval.h @@ -108,6 +108,15 @@ class Interval { } // End of Hurricane namespace. +inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane::Interval* interval ) +{ + w->key( key ); + w->startArray(); + w->write( &interval->getVMin() ); + w->write( &interval->getVMax() ); + w->endArray(); +} + INSPECTOR_PV_SUPPORT(Hurricane::Interval); diff --git a/hurricane/src/hurricane/hurricane/IntrusiveMap.h b/hurricane/src/hurricane/hurricane/IntrusiveMap.h index cffd7474..bb2cd8ca 100644 --- a/hurricane/src/hurricane/hurricane/IntrusiveMap.h +++ b/hurricane/src/hurricane/hurricane/IntrusiveMap.h @@ -449,6 +449,13 @@ template class IntrusiveMap { }; + template + inline GenericCollection getCollection(const IntrusiveMap& intrusiveMap) + // ******************************************************************************************** + { + return intrusiveMap.getElements(); + } + } // End of Hurricane namespace. @@ -470,6 +477,15 @@ inline Hurricane::Record* getRecord ( const Hurricane::IntrusiveMap { return intrusiveMap->_getRecord(); } +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::IntrusiveMap* intrusiveMap ) +{ + w->key( key ); + w->startArray(); + for ( Element* element : intrusiveMap->getElements() ) jsonWrite( w, element ); + w->endArray(); +} + #endif // HURRICANE_INTRUSIVE_MAP diff --git a/hurricane/src/hurricane/hurricane/IntrusiveSet.h b/hurricane/src/hurricane/hurricane/IntrusiveSet.h index 97b9f04b..7f245de7 100644 --- a/hurricane/src/hurricane/hurricane/IntrusiveSet.h +++ b/hurricane/src/hurricane/hurricane/IntrusiveSet.h @@ -470,6 +470,11 @@ template class IntrusiveSet { }; + template + inline GenericCollection getCollection(const IntrusiveSet& intrusiveSet) + // **************************************************************************************** + { return intrusiveSet.getElements(); } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/JsonReader.h b/hurricane/src/hurricane/hurricane/JsonReader.h new file mode 100644 index 00000000..16f62490 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/JsonReader.h @@ -0,0 +1,439 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/JsonReader.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_JSON_READER_H +#define HURRICANE_JSON_READER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Hurricane { + + class Hook; + class Entity; + class Cell; + class Component; + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonStack; + class JsonArray { }; + + +// ------------------------------------------------------------------- +// Class : "JsonAttribute". + + class JsonAttribute { + public: + inline JsonAttribute ( const std::string& key, std::type_index tid ); + inline std::string key () const; + inline std::type_index tid () const; + private: + std::string _key; + std::type_index _tid; + }; + + inline JsonAttribute::JsonAttribute ( const std::string& key, std::type_index tid ) : _key(key), _tid(tid) { } + inline std::string JsonAttribute::key () const { return _key; } + inline std::type_index JsonAttribute::tid () const { return _tid; } + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonObject { + public: + JsonObject ( unsigned long flags ); + virtual ~JsonObject (); + virtual bool isDummy () const; + virtual std::string getTypeName () const = 0; + inline std::string getStackName () const; + bool check ( JsonStack&, string fname ) const; + void print ( std::ostream& ) const; + bool has ( const std::string& key ) const; + void add ( const std::string& key, std::type_index tid ); + void remove ( const std::string& key ); + template inline T get ( JsonStack&, const std::string& key ) const; + inline void copyAttrs ( const JsonObject*, bool reset=false ); + inline void clear (); + inline std::string getName () const; + inline void setName ( const string& ); + template inline T& getObject () const; + template inline void setObject ( T& ) ; + inline bool isBound () const; + virtual JsonObject* clone ( unsigned long flags ) const = 0; + template void toJson ( JsonWriter*, C* object ) const; + virtual void toData ( JsonStack& ); + unsigned int presetId ( JsonStack& ); + template inline void update ( JsonStack&, T ); + inline JsonObject* setFlags ( unsigned long mask ); + inline JsonObject* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + protected: + unsigned long _flags; + std::string _name; + std::vector _stackeds; + std::vector _attributes; + std::vector _collections; + boost::any _object; + }; + + + inline bool JsonObject::isBound () const { return not _object.empty(); } + inline std::string JsonObject::getName () const { return _name; } + inline void JsonObject::setName ( const string& name ) { _name=name; } + inline JsonObject* JsonObject::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonObject* JsonObject::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonObject::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + inline std::string JsonObject::getStackName () const + { return (_name.empty()) ? std::string(".")+getTypeName(): _name; } + + template inline T& JsonObject::getObject () const + { return boost::any_cast(_object); } + + template inline void JsonObject::setObject ( T& t ) + { _object = t; } + + inline void JsonObject::copyAttrs ( const JsonObject* other, bool reset ) + { + if (reset) _attributes.clear(); + for ( size_t i=0 ; i_attributes.size() ; ++i ) + _attributes.push_back( other->_attributes[i] ); + } + + void JsonObject::clear () + { + _stackeds.clear(); + _attributes.clear(); + _collections.clear(); + boost::any emptyAny; + _object.swap( emptyAny ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonKey". + + class JsonKey : public JsonObject { + public: + inline JsonKey ( const std::string& ); + virtual std::string getTypeName () const; + virtual JsonKey* clone ( unsigned long ) const; + private: + std::string _key; + }; + + +// ------------------------------------------------------------------- +// Class : "JsonDummy". + + class JsonDummy : public JsonObject { + public: + inline JsonDummy (); + virtual bool isDummy () const; + virtual std::string getTypeName () const; + void setTypeName ( const std::string& name ); + virtual JsonDummy* clone ( unsigned long ) const; + private: + std::string _typename; + }; + + +} // Hurricane namespace. + + +namespace std { + + template<> + struct less { + inline bool operator() ( const Hurricane::JsonObject* lhs, const Hurricane::JsonObject* rhs ) + { return lhs->getTypeName() < rhs->getTypeName(); } + }; + +} // std namespace. + + +namespace Hurricane { + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + class JsonTypes { + public: + static void initialize (); + static void registerType ( JsonObject* ); + static JsonObject* find ( const std::string& tname ); + private: + JsonTypes (); + ~JsonTypes (); + JsonTypes ( const JsonTypes& ); + void _registerType ( JsonObject* ); + JsonObject* _find ( const std::string& tname ); + private: + static JsonTypes* _jsonTypes; + std::set _jsonObjects; + }; + + +// ------------------------------------------------------------------- +// Class : "HookKey". + + class HookKey { + public: + inline HookKey ( unsigned int id, const std::string& tname ); + inline unsigned int id () const; + inline std::string tname () const; + private: + unsigned int _id; + std::string _tname; + }; + + + inline HookKey::HookKey ( unsigned int id, const std::string& tname ) : _id(id), _tname(tname) { } + inline unsigned int HookKey::id () const { return _id; } + inline std::string HookKey::tname () const { return _tname; } + + inline bool operator< ( const HookKey& lhs, const HookKey& rhs ) + { + if (lhs.id() != rhs.id()) return lhs.id() < rhs.id(); + return lhs.tname() < rhs.tname(); + } + + +// ------------------------------------------------------------------- +// Class : "HookElement". + + class HookElement { + public: + enum Flags { OpenRingStart = (1<<0) + , ClosedRing = (1<<1) + }; + public: + inline HookElement ( Hook*, unsigned long flags=0 ); + inline Hook* hook () const; + inline HookElement* next () const; + inline void setHook ( Hook* ); + inline void setNext ( HookElement* ); + inline unsigned long flags () const; + inline HookElement& setFlags ( unsigned long mask ); + inline HookElement& resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + private: + Hook* _hook; + HookElement* _next; + unsigned long _flags; + }; + + + inline HookElement::HookElement ( Hook* hook, unsigned long flags ) : _hook(hook), _next(NULL), _flags(flags) { } + inline Hook* HookElement::hook () const { return _hook; } + inline HookElement* HookElement::next () const { return _next; } + inline void HookElement::setHook ( Hook* hook ) { _hook = hook; } + inline void HookElement::setNext ( HookElement* element ) { _next = element; } + inline unsigned long HookElement::flags () const { return _flags; } + inline HookElement& HookElement::setFlags ( unsigned long mask ) { _flags |= mask; return *this; } + inline HookElement& HookElement::resetFlags ( unsigned long mask ) { _flags &= ~mask; return *this; } + inline bool HookElement::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + + typedef map HookLut; + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + class JsonStack { + public: + typedef std::pair Element; + public: + static bool hookFromString ( std::string s, unsigned int& id, std::string& tname ); + public: + inline JsonStack (); + inline size_t size () const; + template inline void push_back ( const std::string&, T ); + inline void pop_back ( size_t count=1 ); + inline int rhas ( const std::string& ) const; + template inline T as ( const std::string& ) const; + template inline T as ( int ) const; + template inline T getEntity ( unsigned int ) const; + void addEntity ( unsigned int jsonId, Entity* ); + void addHookLink ( Hook*, unsigned int jsonId, const std::string& jsonNext ); + Hook* getHook ( unsigned int jsonId, const std::string& tname ) const; + bool checkRings () const; + void buildRings () const; + inline void clearHookLinks (); + void print ( std::ostream& ) const; + inline JsonStack* setFlags ( unsigned long mask ); + inline JsonStack* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + inline const Element& operator[] ( int index ) const; + private: + unsigned long _flags; + vector _stack; + std::map _entities; + HookLut _hooks; + }; + + + inline JsonStack::JsonStack () + : _flags(0), _stack(), _entities(), _hooks() + { } + + template inline void JsonStack::push_back ( const std::string& key, T t ) + { + ltrace(51) << "JsonStack::push_back() key:" << key << " value:" << t + << " (" << demangle(typeid(T)) << ")." << endl; + _stack.push_back(std::make_pair(key,boost::any(t))); + } + + inline void JsonStack::pop_back ( size_t count ) + { + while (count--) { + if (_stack.empty()) { + std::cerr << "[ERROR] JsonStack::pop_back(): Stack is empty, but " + << (count+1) << " elements remains to pop." << std::endl; + break; + } + ltrace(51) << "| _stack.pop_back() " << _stack.back().first << endl; + _stack.pop_back(); + } + } + + inline const JsonStack::Element& JsonStack::operator[] ( int index ) const + { + if (index < 0) return _stack[_stack.size()+index]; + return _stack[index]; + } + + inline int JsonStack::rhas ( const std::string& key ) const + { + if (_stack.empty()) return 0; + + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" found at index:" + << (i-(int)_stack.size()) << " (i:" << i << ") " + << "(" << demangle(_stack[i].second.type().name()) << ")." + << endl; + return i-(int)_stack.size(); + } + if (i == 0) break; + --i; + } while ( true ); + + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" not found (returning index: 0)." << endl; + return 0; + } + + template inline T JsonStack::as ( const std::string& key ) const + { + if (not _stack.empty()) { + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::as() k:" << key + << " value:" << demangle(_stack[i].second.type().name()) << std::endl; + return boost::any_cast( _stack[i].second ); + } + if (i == 0) break; + --i; + } while ( true ); + + std::cerr << "[ERROR] JsonStack::as(key): No element with key \"" + << key << "\" in stack." << std::endl; + } else { + std::cerr << "[ERROR] JsonStack::as(key): Stack is empty while searching for key \"" + << key << "\"." << std::endl; + } + + return T(); + } + + template inline T JsonStack::as ( int index ) const + { + size_t i = (index >= 0) ? index : (_stack.size()+index); + return boost::any_cast( _stack[i].second ); + } + + template inline T JsonStack::getEntity ( unsigned int id ) const + { + std::map::const_iterator it = _entities.find(id); + if (it == _entities.end()) return NULL; + return dynamic_cast((*it).second); + } + + inline void JsonStack::clearHookLinks () { _hooks.clear(); } + inline size_t JsonStack::size () const { return _stack.size(); } + inline JsonStack* JsonStack::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonStack* JsonStack::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonStack::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + + template + T JsonObject::get ( JsonStack& stack, const std::string& key ) const + { + int index = stack.rhas(key); + if (index == 0) return T();; + if (stack[index].second.type() == typeid(void*)) return T(); + + return stack.as( index ); + } + + template inline void JsonObject::update ( JsonStack& stack, T hobject ) + { + stack.pop_back( _attributes.size() ); + stack.push_back( getStackName(), hobject ); + setObject( hobject ); + } + + +// ------------------------------------------------------------------- +// Function : Json Parsers. + + Cell* jsonCellParse ( std::string filename ); + Cell* jsonBlobParse ( std::string filename ); + + +} // Hurricane namespace. + +#endif // HURRICANE_JSON_READER_H diff --git a/hurricane/src/hurricane/hurricane/JsonWriter.h b/hurricane/src/hurricane/hurricane/JsonWriter.h new file mode 100644 index 00000000..93304d27 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/JsonWriter.h @@ -0,0 +1,207 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/JsonWriter.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_SLOT_H +#error "JsonWriter.h must be included through Commons.h" +#endif + +#ifndef HURRICANE_JSON_WRITER_H +#define HURRICANE_JSON_WRITER_H + +#include +#include + +namespace rapidjson { + class FileWriteStream; +} + +//namespace Hurricane { + + +// ------------------------------------------------------------------- +// Class : "JsonWriter". + + class JsonWriter { + public: + enum Mode { UsePlugReference = (1<<0) + , DesignBlobMode = (1<<1) + , CellMode = (1<<2) + , RegisterMode = (1<<3) + }; + public: + JsonWriter ( std::string fileName ); + ~JsonWriter (); + void key ( const char* ); + void key ( std::string ); + void startObject (); + void startArray (); + void endObject (); + void endArray (); + void write (); + void write ( const char* ); + void write ( std::string ); + void write ( const std::string* ); + void write ( bool ); + void write ( const bool* ); + void write ( int ); + void write ( const int* ); + void write ( long ); + void write ( const long* ); + void write ( unsigned int ); + void write ( const unsigned int* ); + void write ( unsigned long ); + void write ( const unsigned long* ); + void close (); + JsonWriter* setFlags ( unsigned long mask ); + JsonWriter* resetFlags ( unsigned long mask ); + bool issetFlags ( unsigned long mask ) const; + unsigned long getFlags () const; + private: + JsonWriter ( const JsonWriter& ); + JsonWriter& operator= ( const JsonWriter& ) const; + private: + unsigned long _flags; + size_t _bufferSize; + char* _buffer; + FILE* _file; + rapidjson::FileWriteStream* _stream; + void* _writer; + }; + + +//} // Hurricane namespace. + + +// All jsonWrite() overload are put in the top level namespace, +// in order to facilitate additions from other tools. + +inline void jsonWrite ( JsonWriter* w ) { w->write( ); } +inline void jsonWrite ( JsonWriter* w, const char* s ) { w->write(s); } +inline void jsonWrite ( JsonWriter* w, const std::string* s ) { w->write(s); } +inline void jsonWrite ( JsonWriter* w, std::string s ) { w->write(s); } +inline void jsonWrite ( JsonWriter* w, const bool* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, bool v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const int* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, int v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const long* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, long v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const unsigned int* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, unsigned int v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const unsigned long* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, unsigned long v ) { w->write(v); } + + +//template +//inline void jsonWrite ( JsonWriter* w, const std::string& key, const Type value ) +//{ w->key( key ); w->write( getString(value).c_str() ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const bool* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, bool value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const int* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, int value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const long* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, long value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const unsigned int* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, unsigned int value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const unsigned long* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, unsigned long value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const char* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const std::string& value ) +{ w->key( key ); w->write( value ); } + + +template +inline void jsonWrite ( JsonWriter* w, const C* object ) +{ + if (Hurricane::inltrace(50)) + std::cerr << Hurricane::tab + << "jsonWrite<" << Hurricane::demangle(typeid(C).name()) << "*>(w,object)" << std::endl; + Hurricane::ltracein(50); + + if (object) object->toJson( w ); + else jsonWrite(w); + + Hurricane::ltraceout(50); +} + + +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, const C* object ) +{ + if (Hurricane::inltrace(50)) + std::cerr << Hurricane::tab + << "jsonWrite<" << Hurricane::demangle(typeid(C).name()) << "*>(w,key,object)" + << " key:\"" << key << "\"" << std::endl; + Hurricane::ltracein(50); + + w->key( key ); + if (object) object->toJson( w ); + else jsonWrite(w); + + Hurricane::ltraceout(50); +} + + +#endif // HURRICANE_JSON_WRITER_H diff --git a/hurricane/src/hurricane/hurricane/Layer.h b/hurricane/src/hurricane/hurricane/Layer.h index a32b7372..3d4968c3 100644 --- a/hurricane/src/hurricane/hurricane/Layer.h +++ b/hurricane/src/hurricane/hurricane/Layer.h @@ -95,6 +95,7 @@ namespace Hurricane { inline void _setExtractMask ( const Mask& extractMask ); inline void _setNextOfTechnologyLayerMap ( Layer* layer ); virtual void _onDbuChange ( float scale ); + static const Name& _sgetName ( const Layer* ); private: // Internal: Attributes diff --git a/hurricane/src/hurricane/hurricane/Library.h b/hurricane/src/hurricane/hurricane/Library.h index dbfa24f6..f36ee18a 100644 --- a/hurricane/src/hurricane/hurricane/Library.h +++ b/hurricane/src/hurricane/hurricane/Library.h @@ -95,6 +95,7 @@ class Library : public DBo { public: DataBase* getDataBase() const {return _dataBase;}; public: Library* getLibrary() const {return _library;}; public: const Name& getName() const {return _name;}; + public: string getHierarchicalName () const; public: Library* getLibrary(const Name& name) const {return _libraryMap.getElement(name);}; public: Libraries getLibraries() const {return _libraryMap.getElements();}; public: Cell* getCell(const Name& name) const {return _cellMap.getElement(name);}; @@ -115,6 +116,7 @@ class Library : public DBo { public: virtual string _getTypeName() const {return _TName("Library");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; + public: virtual void _toJson( JsonWriter* ) const; public: LibraryMap& _getLibraryMap() {return _libraryMap;}; public: CellMap& _getCellMap() {return _cellMap;}; public: Library* _getNextOfLibraryLibraryMap() const {return _nextOfLibraryLibraryMap;}; @@ -124,6 +126,16 @@ class Library : public DBo { }; +class JsonLibrary : public JsonDBo { +// ******************************* + + public: JsonLibrary(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonLibrary* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Name.h b/hurricane/src/hurricane/hurricane/Name.h index 0d7452f1..6dcbe0ed 100644 --- a/hurricane/src/hurricane/hurricane/Name.h +++ b/hurricane/src/hurricane/hurricane/Name.h @@ -95,6 +95,12 @@ class Name { INSPECTOR_PV_SUPPORT(Hurricane::Name); +inline void jsonWrite ( JsonWriter* w, Hurricane::Name name ) +{ w->write( getString(name).c_str() ); } + +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::Name name ) +{ w->key( key ); w->write( getString(name).c_str() ); } + #endif // HURRICANE_NAME diff --git a/hurricane/src/hurricane/hurricane/Net.h b/hurricane/src/hurricane/hurricane/Net.h index 195b3302..587e8ffc 100644 --- a/hurricane/src/hurricane/hurricane/Net.h +++ b/hurricane/src/hurricane/hurricane/Net.h @@ -41,7 +41,6 @@ namespace Hurricane { - // **************************************************************************************************** // Net declaration // **************************************************************************************************** @@ -65,6 +64,7 @@ class Net : public Entity { public: Type(const Code& code = UNDEFINED); public: Type(const Type& type); + public: Type(string); public: Type& operator=(const Type& type); @@ -101,6 +101,7 @@ class Net : public Entity { public: Direction(const Code& code = UNDEFINED); public: Direction(const Direction& direction); + public: Direction(string); public: Direction& operator =(const Direction& direction); public: Direction& operator|=(const Direction& direction); @@ -241,9 +242,11 @@ class Net : public Entity { // ****** protected: virtual void _postCreate(); - protected: virtual void _preDestroy(); + public: virtual void _toJson(JsonWriter*) const; + public: virtual void _toJsonSignature(JsonWriter*) const; + public: virtual void _toJsonCollections(JsonWriter*) const; public: virtual string _getTypeName() const {return _TName("Net");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -256,6 +259,22 @@ class Net : public Entity { }; +class JsonNet : public JsonEntity { +// ******************************** + + public: JsonNet(unsigned long flags); + public: virtual ~JsonNet(); + public: virtual string getTypeName() const; + public: virtual JsonNet* clone(unsigned long) const; + public: virtual void toData(JsonStack&); + +// Attributes +// ********** + + protected: bool _autoMaterialize; + protected: Net* _net; + protected: JsonStack* _stack; +}; } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/NetAlias.h b/hurricane/src/hurricane/hurricane/NetAlias.h index 655239d8..161b241c 100644 --- a/hurricane/src/hurricane/hurricane/NetAlias.h +++ b/hurricane/src/hurricane/hurricane/NetAlias.h @@ -60,6 +60,7 @@ namespace Hurricane { void attach ( NetAliasHook* ); void detach (); void detachAll (); + inline void toJson ( JsonWriter* ) const; virtual std::string _getString () const = 0; virtual Record* _getRecord () const; public: @@ -187,5 +188,7 @@ namespace Hurricane { INSPECTOR_P_SUPPORT(Hurricane::NetAliasHook); INSPECTOR_P_SUPPORT(Hurricane::NetMainName); INSPECTOR_P_SUPPORT(Hurricane::NetAliasName); + +inline void jsonWrite ( JsonWriter* w, const Hurricane::NetAliasHook* alias ) { jsonWrite(w,alias->getName()); } #endif // HURRICANE_NET_ALIAS_H diff --git a/hurricane/src/hurricane/hurricane/Occurrence.h b/hurricane/src/hurricane/hurricane/Occurrence.h index 0a477269..bcb67a2a 100644 --- a/hurricane/src/hurricane/hurricane/Occurrence.h +++ b/hurricane/src/hurricane/hurricane/Occurrence.h @@ -32,9 +32,8 @@ class Quark; class BasicLayer; - // **************************************************************************************************** -// Occurente declaration +// Occurrence declaration // **************************************************************************************************** class Occurrence { @@ -98,6 +97,7 @@ class Occurrence { public: string _getTypeName() const { return _TName("Occurrence"); }; public: string _getString() const; public: string getCompactString() const; + public: void toJson(JsonWriter*) const; public: Record* _getRecord() const; public: SharedPath* _getSharedPath() const {return _sharedPath;}; public: Quark* _getQuark() const; @@ -105,6 +105,19 @@ class Occurrence { }; +// **************************************************************************************************** +// JsonOccurrence declaration +// **************************************************************************************************** + + +class JsonOccurrence : public JsonObject { +// ********************************** + + public: JsonOccurrence(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonOccurrence* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Pad.h b/hurricane/src/hurricane/hurricane/Pad.h index 0a72e0f5..2350e977 100644 --- a/hurricane/src/hurricane/hurricane/Pad.h +++ b/hurricane/src/hurricane/hurricane/Pad.h @@ -73,6 +73,8 @@ class Pad : public Component { // Others // ****** + public: virtual void _toJson(JsonWriter*) const; + public: static JsonObject* getJsonObject(unsigned long flags); public: virtual string _getTypeName() const {return _TName("Pad");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -80,6 +82,15 @@ class Pad : public Component { }; +class JsonPad : public JsonComponent { +// *********************************** + + public: JsonPad(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonPad* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Path.h b/hurricane/src/hurricane/hurricane/Path.h index bd5d4fc6..231c864e 100644 --- a/hurricane/src/hurricane/hurricane/Path.h +++ b/hurricane/src/hurricane/hurricane/Path.h @@ -98,6 +98,7 @@ class Path { // ****** public: string getCompactString() const; + public: string getJsonString(unsigned long flags) const; public: string _getTypeName() const { return _TName("Occurrence"); }; public: string _getString() const; public: Record* _getRecord() const; diff --git a/hurricane/src/hurricane/hurricane/Plug.h b/hurricane/src/hurricane/hurricane/Plug.h index 0fac5488..245d0399 100644 --- a/hurricane/src/hurricane/hurricane/Plug.h +++ b/hurricane/src/hurricane/hurricane/Plug.h @@ -103,6 +103,7 @@ class Plug : public Component { protected: virtual void _preDestroy(); public: virtual string getName() const; + public: virtual void _toJson(JsonWriter*) const; public: virtual string _getTypeName() const {return _TName("Plug");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -114,6 +115,25 @@ class Plug : public Component { }; +class JsonPlug : public JsonComponent { +// ************************************ + + public: JsonPlug(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonPlug* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + + +class JsonPlugRef : public JsonObject { +// ************************************ + + public: JsonPlugRef(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonPlugRef* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Point.h b/hurricane/src/hurricane/hurricane/Point.h index 72e8f532..caceb531 100644 --- a/hurricane/src/hurricane/hurricane/Point.h +++ b/hurricane/src/hurricane/hurricane/Point.h @@ -25,7 +25,6 @@ namespace Hurricane { - // **************************************************************************************************** // Point declaration // **************************************************************************************************** @@ -83,14 +82,23 @@ class Point { public: string _getTypeName() const { return _TName("Point"); }; public: string _getString() const; public: Record* _getRecord() const; + public: void toJson(JsonWriter*) const; }; +class JsonPoint : public JsonObject { +// ********************************** + + public: JsonPoint(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonPoint* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. - INSPECTOR_PV_SUPPORT(Hurricane::Point); diff --git a/hurricane/src/hurricane/hurricane/RoutingPad.h b/hurricane/src/hurricane/hurricane/RoutingPad.h index 9c54bc32..bf53293a 100644 --- a/hurricane/src/hurricane/hurricane/RoutingPad.h +++ b/hurricane/src/hurricane/hurricane/RoutingPad.h @@ -1,7 +1,6 @@ - // -*- C++ -*- // -// Copyright (c) BULL S.A. 2000-2013, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved // // This file is part of Hurricane. // @@ -19,10 +18,6 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $Id$ -// // +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | @@ -47,6 +42,9 @@ namespace Hurricane { class Segment; +// ------------------------------------------------------------------- +// Class : "RoutingPad". + class RoutingPad : public Component { public: typedef Component Inherit; @@ -85,6 +83,7 @@ namespace Hurricane { // Miscellaeous. Component* _getEntityAsComponent () const; Segment* _getEntityAsSegment () const; + virtual void _toJson ( JsonWriter* ) const; virtual std::string _getTypeName () const {return _TName("RoutingPad");}; virtual std::string _getString () const; virtual Record* _getRecord () const; @@ -99,6 +98,17 @@ namespace Hurricane { }; +// ------------------------------------------------------------------- +// Class : "JsonRoutingPad". + + class JsonRoutingPad : public JsonComponent { + public: + JsonRoutingPad ( unsigned long flags ); + virtual std::string getTypeName () const; + virtual JsonRoutingPad* clone ( unsigned long flags ) const; + virtual void toData ( JsonStack& ); + }; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Segment.h b/hurricane/src/hurricane/hurricane/Segment.h index 9632fa3c..78e7ab35 100644 --- a/hurricane/src/hurricane/hurricane/Segment.h +++ b/hurricane/src/hurricane/hurricane/Segment.h @@ -26,7 +26,6 @@ namespace Hurricane { - // **************************************************************************************************** // Segment declaration // **************************************************************************************************** @@ -52,8 +51,9 @@ class Segment : public Component { public: virtual bool isMaster() const {return false;}; - public: virtual string _getTypeName() const { return _TName("Segment::SourceHook"); }; + public: virtual string _getTypeName() const { return "Segment::SourceHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; public: class TargetHook : public Hook { @@ -69,8 +69,9 @@ class Segment : public Component { public: virtual bool isMaster() const {return false;}; - public: virtual string _getTypeName() const { return _TName("Segment::TargetHook"); }; + public: virtual string _getTypeName() const { return "Segment::TargetHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; // Attributes @@ -127,12 +128,24 @@ class Segment : public Component { protected: virtual void _preDestroy(); + public: virtual void _toJson(JsonWriter*) const; public: virtual string _getString() const; public: virtual Record* _getRecord() const; }; +// **************************************************************************************************** +// JsonSegment declaration +// **************************************************************************************************** + +class JsonSegment : public JsonComponent { +// *************************************** + + public: JsonSegment(unsigned long flags); +}; + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/SharedPath.h b/hurricane/src/hurricane/hurricane/SharedPath.h index 3f2619a2..20ff5d1f 100644 --- a/hurricane/src/hurricane/hurricane/SharedPath.h +++ b/hurricane/src/hurricane/hurricane/SharedPath.h @@ -97,6 +97,7 @@ class SharedPath { public: SharedPath* getHeadSharedPath() const; public: Instance* getTailInstance() const; public: string getName() const; + public: string getJsonString(unsigned long flags) const; public: Cell* getOwnerCell() const; public: Cell* getMasterCell() const; public: Instances getInstances() const; diff --git a/hurricane/src/hurricane/hurricane/Signature.h b/hurricane/src/hurricane/hurricane/Signature.h new file mode 100644 index 00000000..1ea2d777 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/Signature.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Authors : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/Signature.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_SIGNATURE_H +#define HURRICANE_SIGNATURE_H + +#include "hurricane/DbU.h" + + +namespace Hurricane { + + class Layer; + + +// ------------------------------------------------------------------- +// Class : "Signature". + + class Signature { + public: + enum Type { TypeContact = 1 + , TypeVertical = 2 + , TypeHorizontal = 3 + , TypePad = 4 + , TypePlug = 5 + , TypeNet = 6 + , TypeInstance = 7 + }; + enum DimContacts { ContactDx = 0 + , ContactDy = 1 + , ContactWidth = 2 + , ContactHeight = 3 + }; + enum DimVertical { VerticalWidth = 0 + , VerticalX = 1 + , VerticalDySource = 2 + , VerticalDyTarget = 3 + }; + enum DimHorizontal { HorizontalWidth = 0 + , HorizontalY = 1 + , HorizontalDxSource = 2 + , HorizontalDxTarget = 3 + }; + enum DimPad { PadXMin = 0 + , PadYMin = 1 + , PadXMax = 2 + , PadYMax = 3 + }; + public: + inline Signature (); + inline Signature ( const Signature& ); + inline Type getType () const; + inline std::string getName () const; + inline std::string getMasterNet () const; + inline const Layer* getLayer () const; + inline DbU::Unit getDim ( size_t index ) const; + inline void setType ( Type ); + inline void setName ( const std::string& ); + inline void setMasterNet ( const std::string& ); + void setLayer ( const std::string& ); + inline void setDim ( size_t index, DbU::Unit ); + private: + // Attributes. + Type _type; + std::string _name; // For Cell, Instance & Net. + std::string _masterNet; // For Plug. + const Layer* _layer; // For Components (save Plug). + DbU::Unit _dims[4]; // Dimensions. + }; + + + inline Signature::Signature () + : _type () + , _name () + , _masterNet() + , _layer (NULL) + { + for ( size_t i=0 ; i<4 ; ++i ) _dims[i] = 0; + } + + + inline Signature::Signature ( const Signature& other ) + : _type (other._type ) + , _name (other._name ) + , _masterNet(other._masterNet) + , _layer (other._layer ) + { + for ( size_t i=0 ; i<4 ; ++i ) _dims[i] = other._dims[i]; + } + + + inline Signature::Type Signature::getType () const { return _type; } + inline std::string Signature::getName () const { return _name; } + inline std::string Signature::getMasterNet () const { return _masterNet; } + inline const Layer* Signature::getLayer () const { return _layer; } + inline DbU::Unit Signature::getDim ( size_t index ) const { return _dims[index]; } + inline void Signature::setType ( Signature::Type type ) { _type=type; } + inline void Signature::setName ( const std::string& name ) { _name=name; } + inline void Signature::setMasterNet ( const std::string& masterNet ) { _masterNet=masterNet; } + inline void Signature::setDim ( size_t index, DbU::Unit u ) { _dims[index]=u; } + + +// ------------------------------------------------------------------- +// Class : "Signature". + + class JsonSignature : public JsonObject { + public: + JsonSignature ( unsigned long flags ); + void setSubType ( const std::string& ); + virtual std::string getTypeName () const; + virtual JsonSignature* clone ( unsigned long flags ) const; + virtual void toData ( JsonStack& ); + private: + JsonSignature ( const JsonSignature& ); + JsonSignature& operator= ( const JsonSignature& ) const; + private: + std::string _subTypeName; + }; + +} // End of Hurricane namespace. + +#endif // HURRICANE_SIGNATURE_H diff --git a/hurricane/src/hurricane/hurricane/Tabulation.h b/hurricane/src/hurricane/hurricane/Tabulation.h index b3163116..9202dcb9 100644 --- a/hurricane/src/hurricane/hurricane/Tabulation.h +++ b/hurricane/src/hurricane/hurricane/Tabulation.h @@ -23,7 +23,7 @@ #include "hurricane/Commons.h" #ifndef HURRICANE_SLOT_H -#error "Tabulation.h must be included after Commons.h" +#error "Tabulation.h must be included through Commons.h" #endif namespace Hurricane { diff --git a/hurricane/src/hurricane/hurricane/Transformation.h b/hurricane/src/hurricane/hurricane/Transformation.h index 67c8b5bb..0043fdd9 100644 --- a/hurricane/src/hurricane/hurricane/Transformation.h +++ b/hurricane/src/hurricane/hurricane/Transformation.h @@ -25,7 +25,6 @@ namespace Hurricane { - // **************************************************************************************************** // Transformation declaration // **************************************************************************************************** @@ -45,6 +44,7 @@ class Transformation { public: Orientation(const Code& code = ID); public: Orientation(const Orientation& orientation); + public: Orientation(const string& ); public: Orientation& operator=(const Orientation& orientation); @@ -135,9 +135,18 @@ class Transformation { public: string _getTypeName() const { return _TName("Transformation"); }; public: string _getString() const; public: Record* _getRecord() const; + public: void toJson(JsonWriter*) const; }; +class JsonTransformation : public JsonObject { +// ******************************************* + + public: JsonTransformation(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonTransformation* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; } // End of Hurricane namespace. @@ -203,7 +212,6 @@ INSPECTOR_PV_SUPPORT(Hurricane::Transformation); INSPECTOR_PV_SUPPORT(Hurricane::Transformation::Orientation); IOSTREAM_POINTER_SUPPORT(Hurricane::Transformation::Orientation::Code); - #endif // HURRICANE_TRANSFORMATION diff --git a/hurricane/src/hurricane/hurricane/Vertical.h b/hurricane/src/hurricane/hurricane/Vertical.h index bb3d6c28..28f98cff 100644 --- a/hurricane/src/hurricane/hurricane/Vertical.h +++ b/hurricane/src/hurricane/hurricane/Vertical.h @@ -105,6 +105,8 @@ class Vertical : public Segment { // Others // ****** + public: virtual void _toJson(JsonWriter*) const; + public: static JsonObject* getJsonObject(unsigned long flags); public: virtual string _getTypeName() const {return _TName("Vertical");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -112,6 +114,15 @@ class Vertical : public Segment { }; +class JsonVertical : public JsonSegment { +// ************************************** + + public: JsonVertical(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonVertical* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/isobar/CMakeLists.txt b/hurricane/src/isobar/CMakeLists.txt index 66ea5835..43ae1e09 100644 --- a/hurricane/src/isobar/CMakeLists.txt +++ b/hurricane/src/isobar/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories( ${HURRICANE_SOURCE_DIR}/src/hurricane ${HURRICANE_SOURCE_DIR}/src/viewer ${HURRICANE_SOURCE_DIR}/src/isobar + ${CONFIGURATION_INCLUDE_DIR} ${PYTHON_INCLUDE_PATH} ) set( pyCpps ProxyProperty.cpp diff --git a/hurricane/src/viewer/CMakeLists.txt b/hurricane/src/viewer/CMakeLists.txt index 344b80eb..067890cd 100644 --- a/hurricane/src/viewer/CMakeLists.txt +++ b/hurricane/src/viewer/CMakeLists.txt @@ -28,6 +28,7 @@ hurricane/viewer/CellViewer.h hurricane/viewer/CellPrinter.h hurricane/viewer/CellImage.h + hurricane/viewer/OpenBlobDialog.h hurricane/viewer/RecordModel.h hurricane/viewer/InspectorWidget.h hurricane/viewer/SelectionPopupModel.h @@ -96,6 +97,7 @@ CellViewer.cpp CellPrinter.cpp CellImage.cpp + OpenBlobDialog.cpp RecordModel.cpp InspectorWidget.cpp SelectionPopupModel.cpp diff --git a/hurricane/src/viewer/CellPrinter.cpp b/hurricane/src/viewer/CellPrinter.cpp index 53ef93a3..40acd879 100644 --- a/hurricane/src/viewer/CellPrinter.cpp +++ b/hurricane/src/viewer/CellPrinter.cpp @@ -294,8 +294,8 @@ namespace Hurricane { _paperWidth = _printer->width (); _paperHeight = _printer->height (); - _drawingWidth = _paperWidth - (frameMargin()<<1); - _drawingHeight = _paperHeight - (frameMargin()<<1); + _drawingWidth = _paperWidth /4 - (frameMargin()<<1); + _drawingHeight = _paperHeight/4 - (frameMargin()<<1); _xpaper = (imageOnly) ? 0 : frameMargin(); _ypaper = (imageOnly) ? 0 : frameMargin(); diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index f7dff57d..cdfe7f43 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -32,8 +32,11 @@ #include "vlsisapd/utilities/Path.h" #include "vlsisapd/configuration/Configuration.h" +#include "hurricane/DebugSession.h" #include "hurricane/DataBase.h" +#include "hurricane/Library.h" #include "hurricane/Cell.h" +#include "hurricane/DesignBlob.h" //#include "MapView.h" #include "hurricane/isobar/PyCell.h" #include "hurricane/viewer/Script.h" @@ -46,6 +49,7 @@ #include "hurricane/viewer/ScriptWidget.h" #include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/viewer/GotoWidget.h" +#include "hurricane/viewer/OpenBlobDialog.h" #include "hurricane/viewer/SelectCommand.h" #include "hurricane/viewer/PyCellViewer.h" @@ -393,6 +397,22 @@ namespace Hurricane { action->setVisible( false ); addToMenu( "file.========" ); + action = addToMenu( "file.openDesignBlob" + , tr("&Open Design Blob") + , tr("Reload (restore) the whole Hurricane DataBase state") + , QKeySequence() + , QIcon(":/images/stock_open.png") + ); + connect( action, SIGNAL(triggered()), this, SLOT(openDesignBlob()) ); + action = addToMenu( "file.saveDesignBlob" + , tr("&Save Design Blob") + , tr("Save (dump) the whole Hurricane DataBase state") + , QKeySequence() + , QIcon(":/images/stock_save.png") + ); + connect( action, SIGNAL(triggered()), this, SLOT(saveDesignBlob()) ); + addToMenu( "file.========" ); + action = addToMenu( "file.importCell" , tr("&Import Cell") , tr("Import (convert) a new Cell") @@ -702,6 +722,36 @@ namespace Hurricane { } + void CellViewer::openDesignBlob () + { + QString blobName; + if (OpenBlobDialog::runDialog(this,blobName)) { + string fileName = blobName.toStdString() + ".blob"; + DebugSession::open( 50 ); + Cell* topCell = jsonBlobParse( fileName ); + DebugSession::close(); + + setCell ( topCell ); + } + } + + + void CellViewer::saveDesignBlob () + { + Cell* cell = getCell(); + if (not cell) return; + + string blobName = getString(cell->getName()) + ".blob.json"; + DesignBlob blob ( cell ); + + DebugSession::open( 50 ); + JsonWriter writer ( blobName ); + writer.setFlags( JsonWriter::DesignBlobMode ); + jsonWrite( &writer, &blob ); + DebugSession::close(); + } + + void CellViewer::select ( Occurrence& occurrence ) { if ( _cellWidget ) _cellWidget->select ( occurrence ); } diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index 4a4a99d9..a7a49d32 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -1042,7 +1042,7 @@ namespace Hurricane { // Class : "Hurricane::CellWidget". - int CellWidget::_initialSide = 400; + int CellWidget::_initialSide = 250; CellWidget::CellWidget ( QWidget* parent ) diff --git a/hurricane/src/viewer/OpenBlobDialog.cpp b/hurricane/src/viewer/OpenBlobDialog.cpp new file mode 100644 index 00000000..eb87dd89 --- /dev/null +++ b/hurricane/src/viewer/OpenBlobDialog.cpp @@ -0,0 +1,97 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./OpenBlobDialog.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Warning.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/OpenBlobDialog.h" + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "OpenBlobDialog". + + + OpenBlobDialog::OpenBlobDialog ( QWidget* parent ) + : QDialog (parent) + , _lineEdit(NULL) + { + setWindowTitle( tr("Open Design Blob") ); + + QLabel* label = new QLabel (); + label->setText( tr("Enter the Blob name (without extention \".blob.json\")") ); + label->setFont( Graphics::getNormalFont(true) ); + + _lineEdit = new QLineEdit (); + _lineEdit->setMinimumWidth( 400 ); + + QPushButton* okButton = new QPushButton (); + okButton->setText ( "OK" ); + okButton->setDefault( true ); + + QPushButton* cancelButton = new QPushButton (); + cancelButton->setText( "Cancel" ); + + QHBoxLayout* hLayout1 = new QHBoxLayout (); + hLayout1->addStretch(); + hLayout1->addWidget ( okButton ); + hLayout1->addStretch(); + hLayout1->addWidget ( cancelButton ); + hLayout1->addStretch(); + + QVBoxLayout* vLayout = new QVBoxLayout (); + vLayout->setSizeConstraint ( QLayout::SetFixedSize ); + vLayout->addWidget( label ); + vLayout->addWidget( _lineEdit ); + vLayout->addLayout( hLayout1 ); + + setLayout ( vLayout ); + + connect ( okButton, SIGNAL(clicked()), this, SLOT(accept()) ); + connect ( cancelButton, SIGNAL(clicked()), this, SLOT(reject()) ); + } + + + const QString OpenBlobDialog::getBlobName () const + { return _lineEdit->text(); } + + + bool OpenBlobDialog::runDialog ( QWidget* parent, QString& name ) + { + OpenBlobDialog* dialog = new OpenBlobDialog ( parent ); + bool dialogResult = (dialog->exec() == Accepted); + + name = dialog->getBlobName(); + + delete dialog; + + return dialogResult; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/viewer/hurricane/viewer/CellViewer.h b/hurricane/src/viewer/hurricane/viewer/CellViewer.h index 15705490..0bb9ce08 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/CellViewer.h @@ -136,6 +136,8 @@ namespace Hurricane { void setShowSelection ( bool ); void setState ( shared_ptr& ); void openHistoryCell (); + void openDesignBlob (); + void saveDesignBlob (); void printDisplay (); void print ( QPrinter* ); void imageDisplay (); diff --git a/hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h b/hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h new file mode 100644 index 00000000..b895d4ce --- /dev/null +++ b/hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h @@ -0,0 +1,42 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/viewer/OpenBlobDialog.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_OPEN_BLOB_DIALOG_H +#define HURRICANE_OPEN_BLOB_DIALOG_H + +#include + +class QLineEdit; + + +namespace Hurricane { + + + class OpenBlobDialog : public QDialog { + Q_OBJECT; + public: + static bool runDialog ( QWidget* parent, QString& name ); + const QString getBlobName () const; + protected: + OpenBlobDialog ( QWidget* parent=NULL ); + protected: + QLineEdit* _lineEdit; + }; + + +} // Hurricane namespace. + +#endif // HURRICANE_OPEN_BLOB_DIALOG_H diff --git a/unicorn/src/ExportCellDialog.cpp b/unicorn/src/ExportCellDialog.cpp index caefb8cf..0073c010 100644 --- a/unicorn/src/ExportCellDialog.cpp +++ b/unicorn/src/ExportCellDialog.cpp @@ -78,6 +78,7 @@ namespace Unicorn { formatLabel->setFont ( Graphics::getNormalFont(true) ); hLayout2->addWidget ( formatLabel ); + _formatComboBox->addItem ( tr("JSON (experimental)") , Json ); _formatComboBox->addItem ( tr("Alliance compliant DEF"), AllianceDef ); _formatComboBox->addItem ( tr("ASCII/GDSII (AGDS)") , AsciiGds ); hLayout2->addWidget ( _formatComboBox ); diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index ccdb0c75..08c5e9bd 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -17,6 +17,7 @@ #include #include #include +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/viewer/Script.h" #include "hurricane/viewer/CellViewer.h" @@ -45,8 +46,10 @@ namespace Unicorn { using Hurricane::dbo_ptr; + using Hurricane::DebugSession; using Hurricane::Warning; using Hurricane::PyCellViewer_Link; + using Hurricane::jsonCellParse; using CRL::System; using CRL::Catalog; using CRL::AllianceFramework; @@ -89,6 +92,7 @@ namespace Unicorn { _runUnicornInit(); _importCell.setDialog( _importDialog ); + _importCell.addImporter( "JSON (experimental)" , std::bind( &jsonCellParse , placeholders::_1 ) ); _importCell.addImporter( "BLIF (Yosys/ABC)" , std::bind( &Blif::load , placeholders::_1 ) ); _importCell.addImporter( "ACM/SIGDA (aka MCNC, .bench)", std::bind( &AcmSigda::load , placeholders::_1 ) ); _importCell.addImporter( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) ); @@ -282,8 +286,16 @@ namespace Unicorn { DefExport::drive ( cell, DefExport::WithLEF ); break; case ExportCellDialog::AsciiGds: - GdsDriver gdsDriver ( cell ); - gdsDriver.save( getString(cell->getName())+".agds" ); + { GdsDriver gdsDriver ( cell ); + gdsDriver.save( getString(cell->getName())+".agds" ); + } + break; + case ExportCellDialog::Json: + { DebugSession::open( 50 ); + JsonWriter writer ( cellName.toStdString()+".json" ); + jsonWrite( &writer, cell ); + DebugSession::close(); + } break; } } diff --git a/unicorn/src/unicorn/ExportCellDialog.h b/unicorn/src/unicorn/ExportCellDialog.h index cbc2a44b..652ca747 100644 --- a/unicorn/src/unicorn/ExportCellDialog.h +++ b/unicorn/src/unicorn/ExportCellDialog.h @@ -31,7 +31,7 @@ namespace Unicorn { Q_OBJECT; public: - enum Formats { AllianceDef=1, AsciiGds=2 }; + enum Formats { AllianceDef=1, AsciiGds=2, Json=3 }; public: ExportCellDialog ( QWidget* parent=NULL ); bool runDialog ( QString& name, int& format );