From 6ad644fac29d5c830ae84ab8d2cdfc566f00d6a4 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 30 Mar 2016 17:47:00 +0200 Subject: [PATCH] New relation for slaved ABs. Do *not* delete blockage nets. * Change: In Hurricane, in DataBase::CellDepths() the recursion stop criterion must be Cell::isLeaf() and not Cell::isTerminal() as the second one can be used to hide some levels of hierarchy, and we want all of them in a blob. * New: In Hurricane, in Cell, create a new Slaveds relation to keep track of all the Cells with a slaved abutment box. This work is incomplete as we do not manage the behavior in case of merge or Cell destruction or slaving Cells with aready slaveds ones. Modify Cell::setAbutmentBox() to work in both autonomous and slaved mode. * New: In Hurricane, in Net, add a new type of Net: BLOCKAGE this avoid us to be dependant on the framework pattern recognition. (change propagated to the Python support) * New: In CRL Core, in the various drivers, recognize blockage nets as such and set their type accordingly. * Change: In CRL, in Toolbox::deleteEmptyNets(), preserve blockage Nets. This was the cause of crashs in Kite::BuildPowerRails() as we where trying to use a deleted blockage net... * Bug: In Hurricane, in NetAlias, do not write NetAlias as a name but as a type. They were not read back and moreover staying in the JSON parser stack. --- crlcore/src/ccore/alliance/ap/ApParser.cpp | 3 + crlcore/src/ccore/iccad04/Iccad04Lefdef.cpp | 1 + crlcore/src/ccore/lefdef/LefExport.cpp | 2 +- crlcore/src/ccore/lefdef/LefParser.cpp | 81 ++--- crlcore/src/ccore/toolbox/ToolBox.cpp | 17 +- cumulus/src/plugins/chip/Configuration.py | 1 + hurricane/src/hurricane/Cell.cpp | 334 ++++++++++++++++--- hurricane/src/hurricane/DataBase.cpp | 2 +- hurricane/src/hurricane/JsonReader.cpp | 4 +- hurricane/src/hurricane/Net.cpp | 1 + hurricane/src/hurricane/hurricane/Cell.h | 84 +++++ hurricane/src/hurricane/hurricane/Net.h | 4 +- hurricane/src/hurricane/hurricane/NetAlias.h | 6 +- hurricane/src/isobar/PyNet.cpp | 1 + hurricane/src/isobar/PyNetType.cpp | 1 + katabatic/src/AutoHorizontal.cpp | 8 +- kite/src/BuildPowerRails.cpp | 4 +- kite/src/KiteEngine.cpp | 6 - 18 files changed, 440 insertions(+), 120 deletions(-) diff --git a/crlcore/src/ccore/alliance/ap/ApParser.cpp b/crlcore/src/ccore/alliance/ap/ApParser.cpp index dfba020a..d48843af 100644 --- a/crlcore/src/ccore/alliance/ap/ApParser.cpp +++ b/crlcore/src/ccore/alliance/ap/ApParser.cpp @@ -355,6 +355,9 @@ namespace { net->setType ( Net::Type::CLOCK ); net->setGlobal ( true ); } + if ( _framework->isBLOCKAGE(hName) ) { + net->setType ( Net::Type::BLOCKAGE ); + } } return net; diff --git a/crlcore/src/ccore/iccad04/Iccad04Lefdef.cpp b/crlcore/src/ccore/iccad04/Iccad04Lefdef.cpp index 216ff3fc..aeb4b067 100644 --- a/crlcore/src/ccore/iccad04/Iccad04Lefdef.cpp +++ b/crlcore/src/ccore/iccad04/Iccad04Lefdef.cpp @@ -420,6 +420,7 @@ namespace { DbU::Unit width = sliceHeight * (slices-2); Net* net = Net::create ( cell, "blockageNet" ); + net->setType( Net::Type::BLOCKAGE ); Horizontal::create ( net , BLOCKAGE2 diff --git a/crlcore/src/ccore/lefdef/LefExport.cpp b/crlcore/src/ccore/lefdef/LefExport.cpp index 29a77b51..259d1a3d 100644 --- a/crlcore/src/ccore/lefdef/LefExport.cpp +++ b/crlcore/src/ccore/lefdef/LefExport.cpp @@ -389,7 +389,7 @@ namespace { CHECK_STATUS(_status); #endif - if ( blockageNet != 0 ) { + if ( blockageNet != NULL ) { _status = lefwStartMacroObs (); CHECK_STATUS(_status); diff --git a/crlcore/src/ccore/lefdef/LefParser.cpp b/crlcore/src/ccore/lefdef/LefParser.cpp index b04f744e..f356703e 100644 --- a/crlcore/src/ccore/lefdef/LefParser.cpp +++ b/crlcore/src/ccore/lefdef/LefParser.cpp @@ -1,42 +1,9 @@ - // -*- C++ -*- // -// This file is part of the Coriolis Project. -// Copyright (C) Laboratoire LIP6 - Departement ASIM -// Universite Pierre et Marie Curie +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2016, All Rights Reserved // -// Main contributors : -// Christophe Alexandre -// Sophie Belloeil -// Hugo Clément -// Jean-Paul Chaput -// Damien Dupuis -// Christian Masson -// Marek Sroka -// -// The Coriolis Project is free software; you can redistribute it -// and/or modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// The Coriolis Project 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 -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with the Coriolis Project; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -// USA -// -// License-Tag -// Authors-Tag -// =================================================================== -// -// $Id: CParsLEF.cpp,v 1.28 2007/07/29 15:27:25 jpc Exp $ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | Alliance / Hurricane Interface | // | | @@ -44,30 +11,24 @@ // | E-mail : Christophe.Alexandre@lip6.fr | // | =============================================================== | // | C++ Module : "./LefParser.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ - -# include "hurricane/Warning.h" -# include "hurricane/DataBase.h" -# include "hurricane/BasicLayer.h" -# include "hurricane/ViaLayer.h" -# include "hurricane/Net.h" -# include "hurricane/Pad.h" -# include "hurricane/Vertical.h" -# include "hurricane/Horizontal.h" -# include "hurricane/NetExternalComponents.h" -# include "hurricane/Cell.h" - -# include "crlcore/AllianceFramework.h" -# include "LefDef.h" - -# if HAVE_LEFDEF && defined(LEF_ENABLED) -# include "lefrReader.hpp" -# endif +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/ViaLayer.h" +#include "hurricane/Net.h" +#include "hurricane/Pad.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Cell.h" +#include "crlcore/AllianceFramework.h" +#include "LefDef.h" +#if HAVE_LEFDEF && defined(LEF_ENABLED) +# include "lefrReader.hpp" +#endif # define ONLY_PAD_PINS 1 @@ -110,8 +71,10 @@ namespace { if (!layer) throw Error("No layer for blockage"); - if ( blockageNet == NULL ) + if ( blockageNet == NULL ) { blockageNet = Net::create ( cell, "blockagenet" ); + blockageNet->setType ( Net::Type::BLOCKAGE ); + } Pad::create ( blockageNet, layer, bb ); } diff --git a/crlcore/src/ccore/toolbox/ToolBox.cpp b/crlcore/src/ccore/toolbox/ToolBox.cpp index 80352cd8..8d921bc9 100644 --- a/crlcore/src/ccore/toolbox/ToolBox.cpp +++ b/crlcore/src/ccore/toolbox/ToolBox.cpp @@ -428,15 +428,16 @@ void createContactsRing(Cell* cell) void deleteEmptyNets ( Cell* cell ) { vector nets; - forEach ( Net*, inet, cell->getNets() ) - nets.push_back ( *inet ); + for ( Net* net : cell->getNets() ) + nets.push_back ( net ); - for ( size_t i=0 ; igetComponents().getFirst() - && ( nets[i]->getType() != Net::Type::POWER ) - && ( nets[i]->getType() != Net::Type::GROUND ) - && ( nets[i]->getType() != Net::Type::CLOCK ) ) { - nets[i]->destroy (); + for ( size_t i=0 ; igetComponents().getFirst() + and (nets[i]->getType() != Net::Type::POWER ) + and (nets[i]->getType() != Net::Type::GROUND ) + and (nets[i]->getType() != Net::Type::CLOCK ) + and (nets[i]->getType() != Net::Type::BLOCKAGE) ) { + nets[i]->destroy(); } } } diff --git a/cumulus/src/plugins/chip/Configuration.py b/cumulus/src/plugins/chip/Configuration.py index 5c13b7e3..ef39c905 100644 --- a/cumulus/src/plugins/chip/Configuration.py +++ b/cumulus/src/plugins/chip/Configuration.py @@ -593,6 +593,7 @@ class ChipConf ( object ): self._blockageNet = self._cell.getNet(self._blockageName) if not self._blockageNet: self._blockageNet = Net.create( self._cell, self._blockageName ) + self._blockageNet.setType( Net.Type.BLOCKAGE ) return diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 402bc8e2..112ac796 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -274,6 +274,205 @@ namespace Hurricane { } +// **************************************************************************************************** +// SlavedsRelation implementation +// **************************************************************************************************** + + const Name Cell::SlavedsRelation::_name = "Cell::SlavedsRelation"; + + + Cell::SlavedsRelation::SlavedsRelation ( Cell* masterOwner ) + : Relation (masterOwner) + { } + + + Cell::SlavedsRelation* Cell::SlavedsRelation::create ( Cell* masterOwner ) + { + SlavedsRelation* relation = new SlavedsRelation(masterOwner); + + relation->_postCreate(); + + return relation; + } + + + void Cell::SlavedsRelation::_preDestroy () + { + Relation::_preDestroy(); + } + + + Cell::SlavedsRelation* Cell::SlavedsRelation::get ( const Cell* cell ) + { + if (not cell) + throw Error( "Can't get Cell::SlavedsRelation : empty cell" ); + Property* property = cell->getProperty( staticGetName() ); + if (property) { + SlavedsRelation* relation = dynamic_cast(property); + if (not relation ) + throw Error ( "Bad Property type: Must be a SlavedsRelation" ); + return relation; + } + return NULL; + } + + + Name Cell::SlavedsRelation::staticGetName () { return _name; } + Name Cell::SlavedsRelation::getName () const { return _name; } + string Cell::SlavedsRelation::_getTypeName () const { return "Cell::SlavedsRelation"; } + + + Record* Cell::SlavedsRelation::_getRecord () const + { + Record* record = Relation::_getRecord(); + return record; + } + + + bool Cell::SlavedsRelation::hasJson () const + { return true; } + + + void Cell::SlavedsRelation::toJson ( JsonWriter* w, const DBo* owner ) const + { + w->startObject(); + std::string tname = getString( staticGetName() ); + if (getMasterOwner() == owner) { + jsonWrite( w, "@typename" , tname ); + jsonWrite( w, "_refcount" , getOwners().getSize() ); + } else { + tname.insert( 0, "&" ); + jsonWrite( w, "@typename", tname ); + + Cell* masterOwner = dynamic_cast( getMasterOwner() ); + if (masterOwner) { + jsonWrite( w, "_masterOwner", masterOwner->getHierarchicalName() ); + } else { + cerr << Error( "SlavedsRelation::toJson(): Master owner is not a Cell (%s)." + , getString(owner).c_str() + ) << endl; + jsonWrite( w, "_masterOwner", "" ); + } + } + w->endObject(); + } + + +// **************************************************************************************************** +// SlavedsRelation::JsonProperty implementation +// **************************************************************************************************** + + + Initializer jsonSlavedsRelationInit ( 10 ); + + + Cell::SlavedsRelation::JsonProperty::JsonProperty ( unsigned long flags ) + : JsonObject(flags) + { + add( "_refcount" , typeid(int64_t) ); + } + + + string Cell::SlavedsRelation::JsonProperty::getTypeName () const + { return getString(Cell::SlavedsRelation::staticGetName()); } + + + void Cell::SlavedsRelation::JsonProperty::initialize () + { JsonTypes::registerType( new Cell::SlavedsRelation::JsonProperty (JsonWriter::RegisterMode) ); } + + + Cell::SlavedsRelation::JsonProperty* Cell::SlavedsRelation::JsonProperty::clone ( unsigned long flags ) const + { return new Cell::SlavedsRelation::JsonProperty ( flags ); } + + + void Cell::SlavedsRelation::JsonProperty::toData ( JsonStack& stack ) + { + check( stack, "Cell::SlavedsRelation::JsonProperty::toData" ); + + DBo* dbo = stack.back_dbo(); + unsigned int refcount = get( stack, "_refcount" ); + SlavedsRelation* relation = NULL; + Cell* cell = dynamic_cast( dbo ); + + ltrace(51) << "topDBo:" << dbo << endl; + + if (cell) { + relation = SlavedsRelation::get( cell ); + if (not relation) { + string tag = cell->getHierarchicalName()+"::"+getString(SlavedsRelation::staticGetName()); + relation = dynamic_cast( SharedProperty::getOrphaned( tag ) ); + + if (not relation) { + relation = Cell::SlavedsRelation::create( cell ); + SharedProperty::addOrphaned( tag, relation ); + } + SharedProperty::refOrphaned( tag ); + SharedProperty::countOrphaned( tag, refcount ); + cell->put( relation ); + } + relation->_setMasterOwner( cell ); + } + + update( stack, relation ); + } + + +// **************************************************************************************************** +// SlavedsRelation::JsonPropertyRef implementation +// **************************************************************************************************** + + + Initializer jsonSlavedsRelationRefInit ( 10 ); + + + Cell::SlavedsRelation::JsonPropertyRef::JsonPropertyRef ( unsigned long flags ) + : JsonObject(flags) + { + add( "_masterOwner", typeid(string) ); + } + + + string Cell::SlavedsRelation::JsonPropertyRef::getTypeName () const + { return string("&")+getString(Cell::SlavedsRelation::staticGetName()); } + + + void Cell::SlavedsRelation::JsonPropertyRef::initialize () + { JsonTypes::registerType( new Cell::SlavedsRelation::JsonPropertyRef (JsonWriter::RegisterMode) ); } + + + Cell::SlavedsRelation::JsonPropertyRef* Cell::SlavedsRelation::JsonPropertyRef::clone ( unsigned long flags ) const + { return new Cell::SlavedsRelation::JsonPropertyRef ( flags ); } + + + void Cell::SlavedsRelation::JsonPropertyRef::toData ( JsonStack& stack ) + { + check( stack, "Cell::SlavedsRelation::JsonPropertyRef::toData" ); + + DBo* dbo = stack.back_dbo(); + string masterName = get( stack, "_masterOwner" ); + SlavedsRelation* relation = NULL; + Cell* cell = dynamic_cast( dbo ); + string tag = masterName+"::"+getString(SlavedsRelation::staticGetName()); + + if (cell) { + if (not relation) { + relation = dynamic_cast( SharedProperty::getOrphaned( tag ) ); + if (not relation) { + relation = Cell::SlavedsRelation::create( cell ); + SharedProperty::addOrphaned( tag, relation ); + } + } + + if (relation) { + cell->put( relation ); + SharedProperty::refOrphaned( tag ); + } + } + + update( stack, relation ); + } + + // **************************************************************************************************** // Cell Slice related implementation // **************************************************************************************************** @@ -564,7 +763,26 @@ void Cell::setName(const Name& name) } void Cell::setAbutmentBox(const Box& abutmentBox) -// ********************************************** +// *********************************************** +{ + SlavedsRelation* slaveds = SlavedsRelation::get( this ); + if (not slaveds or (this == slaveds->getMasterOwner())) { + _setAbutmentBox( abutmentBox ); + + if (getFlags().isset(Flags::SlavedAb)) return; + + for ( Cell* slavedCell : SlavedsSet(this) ) + slavedCell->_setAbutmentBox( abutmentBox ); + } else { + cerr << Error( "Cell::setAbutmentBox(): Abutment box of \"%s\" is slaved to \"%s\"." + , getString(getName()).c_str() + , getString(static_cast(slaveds->getMasterOwner())->getName()).c_str() + ) << endl; + } +} + +void Cell::_setAbutmentBox(const Box& abutmentBox) +// *********************************************** { if (abutmentBox != _abutmentBox) { if (not _abutmentBox.isEmpty() and @@ -573,12 +791,6 @@ void Cell::setAbutmentBox(const Box& abutmentBox) _abutmentBox = abutmentBox; _fit( _abutmentBox ); } - - for ( Instance* instance : getInstances() ) { - Cell* masterCell = instance->getMasterCell(); - if (masterCell->getFlags().isset(Flags::SlavedAb)) - masterCell->setAbutmentBox( abutmentBox ); - } } @@ -730,7 +942,6 @@ Cell* Cell::getCloneMaster() const UniquifyRelation* uniquify = UniquifyRelation::get( this ); if (not uniquify) return const_cast(this); - uniquify = UniquifyRelation::get( this ); return dynamic_cast( uniquify->getMasterOwner() ); } @@ -869,7 +1080,6 @@ void Cell::slaveAbutmentBox ( Cell* topCell ) return; } - _flags.set( Flags::SlavedAb ); if (not isUnique()) { cerr << Error( "Cell::slaveAbutmentBox(): %s is *not* unique, action cancelled." , getString(this).c_str() ) << endl; @@ -907,15 +1117,16 @@ void Cell::_slaveAbutmentBox ( Cell* topCell ) } } - setAbutmentBox( topCell->getAbutmentBox() ); + _setAbutmentBox( topCell->getAbutmentBox() ); + + SlavedsRelation* slaveds = SlavedsRelation::get( topCell ); + if (not slaveds) { + slaveds = SlavedsRelation::create( topCell ); + } + put( slaveds ); + _flags.set( Flags::SlavedAb ); //_changeQuadTree( topCell ); - - for ( Instance* instance : getInstances() ) { - Cell* masterCell = instance->getMasterCell(); - if (masterCell->getFlags().isset(Flags::SlavedAb)) - masterCell->_slaveAbutmentBox( topCell ); - } } @@ -1138,29 +1349,14 @@ void Cell::_toJsonCollections(JsonWriter* writer) const if (not _flags) return ""; string s = "<"; - if (_flags & Pad) { - s += "Pad"; - } - if (_flags & Terminal) { - if (s.size() > 1) s += "|"; - s += "Terminal"; - } - if (_flags & FlattenLeaf) { - if (s.size() > 1) s += "|"; - s += "FlattenLeaf"; - } - if (_flags & FlattenedNets) { - if (s.size() > 1) s += "|"; - s += "FlattenedNets"; - } - if (_flags & Placed) { - if (s.size() > 1) s += "|"; - s += "Placed"; - } - if (_flags & Routed) { - if (s.size() > 1) s += "|"; - s += "Routed"; - } + if (_flags & Pad ) { s += "Pad"; } + if (_flags & Terminal ) { if (s.size() > 1) s += "|"; s += "Terminal"; } + if (_flags & FlattenLeaf ) { if (s.size() > 1) s += "|"; s += "FlattenLeaf"; } + if (_flags & FlattenedNets) { if (s.size() > 1) s += "|"; s += "FlattenedNets"; } + if (_flags & Placed ) { if (s.size() > 1) s += "|"; s += "Placed"; } + if (_flags & Routed ) { if (s.size() > 1) s += "|"; s += "Routed"; } + if (_flags & SlavedAb ) { if (s.size() > 1) s += "|"; s += "SlavedAb"; } + if (_flags & Materialized ) { if (s.size() > 1) s += "|"; s += "Materialized"; } s += ">"; return s; @@ -1227,6 +1423,66 @@ void Cell::_toJsonCollections(JsonWriter* writer) const } +// **************************************************************************************************** +// Cell::SlavedsSet implementation +// **************************************************************************************************** + + Cell::SlavedsSet::Locator::Locator ( const Cell* cell ) + : Hurricane::Locator() + , _dboLocator (NULL) + { + SlavedsRelation* slaveds = SlavedsRelation::get( cell ); + if (slaveds) { + _dboLocator = slaveds->getSlaveOwners().getLocator(); + } + } + + + Locator* Cell::SlavedsSet::Locator::getClone () const + { return new Locator(*this); } + + + Cell* Cell::SlavedsSet::Locator::getElement () const + { return (_dboLocator and _dboLocator->isValid()) + ? dynamic_cast(_dboLocator->getElement()) : NULL; } + + + bool Cell::SlavedsSet::Locator::isValid () const + { return (_dboLocator and _dboLocator->isValid()); } + + + void Cell::SlavedsSet::Locator::progress () + { + _dboLocator->progress(); + } + + + string Cell::SlavedsSet::Locator::_getString () const + { + string s = "<" + _TName("Cell::SlavedsSet::Locator") + + getString(getElement()) + + ">"; + return s; + } + + + Collection* Cell::SlavedsSet::getClone () const + { return new SlavedsSet(*this); } + + + Locator* Cell::SlavedsSet::getLocator () const + { return new Locator(_cell); } + + + string Cell::SlavedsSet::_getString () const + { + string s = "<" + _TName("Cell_SlavedsSet") + " " + + getString(_cell->getName()) + + ">"; + return s; + } + + // **************************************************************************************************** // Cell::InstanceMap implementation // **************************************************************************************************** diff --git a/hurricane/src/hurricane/DataBase.cpp b/hurricane/src/hurricane/DataBase.cpp index 0b4d5fbc..cc070d68 100644 --- a/hurricane/src/hurricane/DataBase.cpp +++ b/hurricane/src/hurricane/DataBase.cpp @@ -77,7 +77,7 @@ namespace { int depth = 0; - if (not cellDepth.first->isTerminal()) { + if (not cellDepth.first->isLeaf()) { for ( Instance* instance : cellDepth.first->getInstances() ) { Cell* masterCell = instance->getMasterCell(); pair& masterDepth = *(_cellMap.find( masterCell )); diff --git a/hurricane/src/hurricane/JsonReader.cpp b/hurricane/src/hurricane/JsonReader.cpp index e134e5ac..b6b0f260 100644 --- a/hurricane/src/hurricane/JsonReader.cpp +++ b/hurricane/src/hurricane/JsonReader.cpp @@ -334,8 +334,8 @@ namespace Hurricane { JsonReader::~JsonReader () { close(); - delete _buffer; - delete _handler; + delete [] _buffer; + delete _handler; } diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index 796ef531..ed5db93a 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -799,6 +799,7 @@ Net::Type::Type(string s) else if (s == "CLOCK" ) _code = CLOCK; else if (s == "POWER" ) _code = POWER; else if (s == "GROUND" ) _code = GROUND; + else if (s == "BLOCKAGE" ) _code = BLOCKAGE; } Net::Type& Net::Type::operator=(const Type& type) diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 7da52bbb..82d32077 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -173,6 +173,70 @@ class Cell : public Entity { const Cell* _cell; }; + class SlavedsRelation : public Relation { + public: + static SlavedsRelation* create ( Cell* ); + static SlavedsRelation* get ( const Cell* ); + virtual Name getName () const; + static Name staticGetName (); + virtual bool hasJson () const; + virtual void toJson ( JsonWriter*, const DBo* ) const; + inline void _setOwner ( Cell* ); + virtual string _getTypeName () const; + virtual Record* _getRecord () const; + private: + static const Name _name; + private: + SlavedsRelation ( Cell* ); + protected: + virtual void _preDestroy (); + + public: + class JsonProperty : public JsonObject { + public: + static void initialize (); + JsonProperty ( unsigned long flags ); + virtual string getTypeName () const; + virtual JsonProperty* clone ( unsigned long ) const; + virtual void toData ( JsonStack& ); + }; + public: + class JsonPropertyRef : public JsonObject { + public: + static void initialize (); + JsonPropertyRef ( unsigned long flags ); + virtual string getTypeName () const; + virtual JsonPropertyRef* clone ( unsigned long ) const; + virtual void toData ( JsonStack& ); + }; + }; + + class SlavedsSet : public Collection { + public: + // Sub-Class: Locator. + class Locator : public Hurricane::Locator { + public: + Locator ( const Cell* ); + inline Locator ( const Locator& ); + virtual Cell* getElement () const; + virtual Hurricane::Locator* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + Hurricane::Locator* _dboLocator; + }; + + public: + inline SlavedsSet ( const Cell* cell ); + inline SlavedsSet ( const SlavedsSet& ); + virtual Hurricane::Collection* getClone () const; + virtual Hurricane::Locator* getLocator () const; + virtual string _getString () const; + protected: + const Cell* _cell; + }; + class InstanceMap : public IntrusiveMap { // **************************************************** @@ -327,6 +391,7 @@ class Cell : public Entity { public: void _slaveAbutmentBox(Cell*); public: void _changeQuadTree(Cell*); public: void _setShuntedPath(Path path) { _shuntedPath=path; } + protected: void _setAbutmentBox(const Box& abutmentBox); public: virtual void _toJson(JsonWriter*) const; public: virtual void _toJsonCollections(JsonWriter*) const; @@ -477,6 +542,25 @@ inline void Cell::UniquifyRelation::_setOwner ( Cell* owner ) inline void Cell::UniquifyRelation::_setDuplicates ( unsigned int duplicates ) { _duplicates=duplicates; } +inline Cell::SlavedsSet::Locator::Locator ( const Locator& other ) + : Hurricane::Locator() + , _dboLocator(other._dboLocator) +{ } + +inline Cell::SlavedsSet::SlavedsSet ( const Cell* cell ) + : Hurricane::Collection() + , _cell(cell) +{ } + +inline Cell::SlavedsSet::SlavedsSet ( const SlavedsSet& other ) + : Hurricane::Collection() + , _cell(other._cell) +{ } + + +inline void Cell::SlavedsRelation::_setOwner ( Cell* owner ) { _setMasterOwner(owner); } + + class JsonCell : public JsonEntity { // ********************************* diff --git a/hurricane/src/hurricane/hurricane/Net.h b/hurricane/src/hurricane/hurricane/Net.h index 39b42c0a..6a5df273 100644 --- a/hurricane/src/hurricane/hurricane/Net.h +++ b/hurricane/src/hurricane/hurricane/Net.h @@ -58,7 +58,7 @@ class Net : public Entity { public: class Type { // *************** - public: enum Code {UNDEFINED=0, LOGICAL=1, CLOCK=2, POWER=3, GROUND=4}; + public: enum Code {UNDEFINED=0, LOGICAL=1, CLOCK=2, POWER=3, GROUND=4, BLOCKAGE=5}; private: Code _code; @@ -214,6 +214,7 @@ class Net : public Entity { public: bool isGlobal () const {return _isGlobal;}; public: bool isExternal () const {return _isExternal;}; public: bool isAutomatic() const {return _isAutomatic;}; + public: bool isBlockage () const {return (_type == Type::BLOCKAGE);}; public: bool isLogical () const {return (_type == Type::LOGICAL);}; public: bool isClock () const {return (_type == Type::CLOCK);}; public: bool isPower () const {return (_type == Type::POWER);}; @@ -367,6 +368,7 @@ inline std::string getString case Hurricane::Net::Type::CLOCK: return "CLOCK"; case Hurricane::Net::Type::POWER: return "POWER"; case Hurricane::Net::Type::GROUND: return "GROUND"; + case Hurricane::Net::Type::BLOCKAGE: return "BLOCKAGE"; } return "ABNORMAL"; } diff --git a/hurricane/src/hurricane/hurricane/NetAlias.h b/hurricane/src/hurricane/hurricane/NetAlias.h index c8989f89..cc094354 100644 --- a/hurricane/src/hurricane/hurricane/NetAlias.h +++ b/hurricane/src/hurricane/hurricane/NetAlias.h @@ -203,6 +203,10 @@ 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()); } +inline void jsonWrite ( JsonWriter* w, const Hurricane::NetAliasHook* alias ) +{ + const Hurricane::NetAliasName* aliasName = dynamic_cast( alias ); + if (aliasName) jsonWrite(w,aliasName); +} #endif // HURRICANE_NET_ALIAS_H diff --git a/hurricane/src/isobar/PyNet.cpp b/hurricane/src/isobar/PyNet.cpp index 41d73953..010b2108 100644 --- a/hurricane/src/isobar/PyNet.cpp +++ b/hurricane/src/isobar/PyNet.cpp @@ -68,6 +68,7 @@ extern "C" { case Net::Type::CLOCK : return ( Net::Type(Net::Type::CLOCK) ); case Net::Type::POWER : return ( Net::Type(Net::Type::POWER) ); case Net::Type::GROUND : return ( Net::Type(Net::Type::GROUND) ); + case Net::Type::BLOCKAGE : return ( Net::Type(Net::Type::BLOCKAGE) ); } return ( Net::Type(Net::Type::UNDEFINED) ); diff --git a/hurricane/src/isobar/PyNetType.cpp b/hurricane/src/isobar/PyNetType.cpp index 32bac744..1bf5ebe0 100644 --- a/hurricane/src/isobar/PyNetType.cpp +++ b/hurricane/src/isobar/PyNetType.cpp @@ -98,6 +98,7 @@ extern "C" { LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::CLOCK ,"CLOCK" ); LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::POWER ,"POWER" ); LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::GROUND ,"GROUND" ); + LoadObjectConstant(PyTypeNetType.tp_dict,Net::Type::BLOCKAGE ,"BLOCKAGE" ); } diff --git a/katabatic/src/AutoHorizontal.cpp b/katabatic/src/AutoHorizontal.cpp index b270d5f1..d1717f6a 100644 --- a/katabatic/src/AutoHorizontal.cpp +++ b/katabatic/src/AutoHorizontal.cpp @@ -92,7 +92,13 @@ namespace Katabatic { for ( ; gcell != end ; gcell = gcell->getRight() ) { if ( !gcell ) { - cerr << Error("AutoHorizontal::create() : NULL GCell.") << endl; + cerr << Error( "AutoHorizontal::create() : NULL GCell under %s\n" + " begin:%s\n" + " end: %s" + , getString(this).c_str() + , getString(source->getGCell()).c_str() + , getString(target->getGCell()).c_str() + ) << endl; break; } gcell->addHSegment ( this ); diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index 6c759cb3..eebbaa14 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -1290,8 +1290,10 @@ namespace Kite { if (not _blockageNet) { _blockageNet = getCell()->getNet("blockagenet"); - if (not _blockageNet) + if (not _blockageNet) { _blockageNet = Net::create( getCell(), "blockagenet" ); + _blockageNet->setType( Net::Type::BLOCKAGE ); + } NetRoutingState* state = getRoutingState( _blockageNet, Katabatic::KbCreate ); state->setFlags( NetRoutingState::Fixed ); diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index cceb836e..09e475ba 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -322,14 +322,8 @@ namespace Kite { if (not _knik) { unsigned int flags = Cell::Flags::WarnOnUnplacedInstances; flags |= (mode & KtBuildGlobalRouting) ? Cell::Flags::BuildRings : 0; - //if (not cell->isFlattenedNets()) cell->flattenNets( flags ); cell->flattenNets( flags ); cell->createRoutingPadRings( Cell::Flags::BuildRings ); - - // Test signals from . - //DebugSession::addToTrace( getCell(), "core.snx_inst.a2_x2_8_sig" ); - //DebugSession::addToTrace( getCell(), "m_clock" ); - //DebugSession::addToTrace( getCell(), "a2_x2_8_sig" ); KatabaticEngine::chipPrep();