1888 lines
51 KiB
C++
1888 lines
51 KiB
C++
//
|
|
// This file is part of the Coriolis Project.
|
|
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
|
// Universite Pierre et Marie Curie
|
|
//
|
|
// Main contributors :
|
|
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
|
|
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
|
|
// Hugo Clément <Hugo.Clement@lip6.fr>
|
|
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
|
|
// Damien Dupuis <Damien.Dupuis@lip6.fr>
|
|
// Christian Masson <Christian.Masson@lip6.fr>
|
|
// Marek Sroka <Marek.Sroka@lip6.fr>
|
|
//
|
|
// 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
|
|
//
|
|
//
|
|
// Date : 29/01/2004
|
|
// Author : Hugo Clément <Hugo.Clement@lip6.fr>
|
|
//
|
|
// Authors-Tag
|
|
|
|
#include "math.h"
|
|
#include "hurricane/Pin.h"
|
|
#include "hurricane/Library.h"
|
|
#include "hurricane/UpdateSession.h"
|
|
#include "crlcore/Utilities.h"
|
|
#include "crlcore/LefDefExtension.h"
|
|
#include "crlcore/ToolBox.h"
|
|
#include "crlcore/CellGauge.h"
|
|
#include "crlcore/RoutingGauge.h"
|
|
#include "nimbus/Grid.h"
|
|
#include "nimbus/Fence.h"
|
|
#include "nimbus/GCell.h"
|
|
#include "nimbus/GCells.h"
|
|
#include "nimbus/RoutTools.h"
|
|
#include "nimbus/SplitterContact.h"
|
|
#include "nimbus/NimbusEngine.h"
|
|
|
|
namespace Nimbus {
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_GCells declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Nimbus_GCells : public Collection<GCell*> {
|
|
|
|
public: typedef Collection<GCell*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<GCell*> {
|
|
|
|
public: typedef Hurricane::Locator<GCell*> Inherit;
|
|
|
|
private: const GCellSet* _nbset;
|
|
private: GCellSet::iterator _nbit;
|
|
|
|
public: Locator(const GCellSet* nbset, GCellSet::iterator nbit);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual GCell* getElement() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
private: const GCellSet* _nbset;
|
|
private: GCellSet::iterator _nbit;
|
|
|
|
public: Nimbus_GCells(const GCellSet* nbset);
|
|
public: Nimbus_GCells(const Nimbus_GCells& gcelles);
|
|
|
|
public: Nimbus_GCells& operator=(const Nimbus_GCells& gcelles);
|
|
|
|
public: virtual Collection<GCell*>* getClone() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_ColumnGCells declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Nimbus_ColumnGCells : public Collection<GCell*> {
|
|
|
|
public: typedef Collection<GCell*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<GCell*> {
|
|
|
|
public: typedef Hurricane::Locator<GCell*> Inherit;
|
|
|
|
private: const GCell* _gcell;
|
|
|
|
public: Locator(const GCell* gcell);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual GCell* getElement() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
private: const GCell* _upperGCell;
|
|
|
|
public: Nimbus_ColumnGCells(const GCell* upperGCell);
|
|
public: Nimbus_ColumnGCells(const Nimbus_ColumnGCells& gcelles);
|
|
|
|
public: Nimbus_ColumnGCells& operator=(const Nimbus_ColumnGCells& gcelles);
|
|
|
|
public: virtual Collection<GCell*>* getClone() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_RowGCells declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Nimbus_RowGCells : public Collection<GCell*> {
|
|
|
|
public: typedef Collection<GCell*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<GCell*> {
|
|
|
|
public: typedef Hurricane::Locator<GCell*> Inherit;
|
|
|
|
private: const GCell* _gcell;
|
|
|
|
public: Locator(const GCell* gcell);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual GCell* getElement() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
private: const GCell* _leftGCell;
|
|
|
|
public: Nimbus_RowGCells(const GCell* left);
|
|
public: Nimbus_RowGCells(const Nimbus_RowGCells& gcelles);
|
|
|
|
public: Nimbus_RowGCells& operator=(const Nimbus_RowGCells& gcelles);
|
|
|
|
public: virtual Collection<GCell*>* getClone() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_Fences declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Nimbus_Fences : public Collection<Fence*> {
|
|
|
|
public: typedef Collection<Fence*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<Fence*> {
|
|
|
|
public: typedef Hurricane::Locator<Fence*> Inherit;
|
|
|
|
private: const FenceSet* _fcset;
|
|
private: FenceSet::iterator _fcit;
|
|
|
|
public: Locator(const FenceSet* fcset, FenceSet::iterator fcit);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual Fence* getElement() const;
|
|
public: virtual Hurricane::Locator<Fence*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
private: const FenceSet* _fcset;
|
|
private: FenceSet::iterator _fcit;
|
|
|
|
public: Nimbus_Fences(const FenceSet* fcset);
|
|
public: Nimbus_Fences(const Nimbus_Fences& fences);
|
|
|
|
public: Nimbus_Fences& operator=(const Nimbus_Fences& fences);
|
|
|
|
public: virtual Collection<Fence*>* getClone() const;
|
|
public: virtual Hurricane::Locator<Fence*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_Layers declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Nimbus_Layers : public Collection<Layer*> {
|
|
|
|
public: typedef Collection<Layer*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<Layer*> {
|
|
|
|
public: typedef Hurricane::Locator<Layer*> Inherit;
|
|
|
|
private: const set<Layer*>* _lset;
|
|
private: set<Layer*>::iterator _lit;
|
|
|
|
public: Locator(const set<Layer*>* lset, set<Layer*>::iterator lit);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual Layer* getElement() const;
|
|
public: virtual Hurricane::Locator<Layer*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
private: const set<Layer*>* _lset;
|
|
private: set<Layer*>::iterator _lit;
|
|
|
|
public: Nimbus_Layers(const set<Layer*>* lset);
|
|
public: Nimbus_Layers(const Nimbus_Layers& layers);
|
|
|
|
public: Nimbus_Layers& operator=(const Nimbus_Layers& layers);
|
|
|
|
public: virtual Collection<Layer*>* getClone() const;
|
|
public: virtual Hurricane::Locator<Layer*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
void NimbusEngine::_preCreate(Cell* cell)
|
|
// **************************************
|
|
{
|
|
if ( cell->isTerminal() )
|
|
throw Error("Won't create Nimbus on a standard cell");
|
|
|
|
#if CORIOLIS_2_DEPRECATED
|
|
if (cell->getLibrary() == library) throw Error("Won't create Nimbus on a standard cell");
|
|
string libname (getString(library->getName()));
|
|
|
|
// ********************************************************************************************
|
|
//CellGauge* stdCellGauge(NULL);
|
|
|
|
// Check for CellGauge of library
|
|
CellGauge* cellGauge = AllianceFramework::get()->getCellGauge(library->getName());
|
|
if (cellGauge)
|
|
{
|
|
//stdCellGauge = cellGauges[libname];
|
|
cmess1 << " o Using existing cell gauge for library: <" << libname << ">" << endl;
|
|
}
|
|
else
|
|
{
|
|
//cerr << error << endl;
|
|
cmess1 << " o Creating cell gauge for library " << libname << endl;
|
|
|
|
// read std datas
|
|
Cells cells = library->getCells();
|
|
CellLocator cellLocator = cells.getLocator();
|
|
if (! cellLocator.isValid())
|
|
{
|
|
string message = "Invalid standard cell library ";
|
|
message += getString(library->getName());
|
|
throw Error ( message );
|
|
}
|
|
Cell* gaugeCell = cellLocator.getElement();
|
|
|
|
DbU::Unit sliceHeight = gaugeCell->getAbutmentBox().getHeight();
|
|
DbU::Unit pitch = gaugeCell->getAbutmentBox().getWidth();
|
|
|
|
cellLocator.progress();
|
|
while (cellLocator.isValid())
|
|
{
|
|
gaugeCell = cellLocator.getElement();
|
|
|
|
if (gaugeCell->getAbutmentBox().getHeight() != sliceHeight)
|
|
throw Error ("Inconsistent standard cell library");
|
|
|
|
if (gaugeCell->getAbutmentBox().getWidth() < pitch)
|
|
pitch = gaugeCell->getAbutmentBox().getWidth();
|
|
|
|
cellLocator.progress();
|
|
}
|
|
pitch = DbU::lambda (DbU::getLambda(pitch) / 2);
|
|
DbU::Unit sliceStep = pitch;
|
|
|
|
// Creating CellGauge in the CDataBase
|
|
cmess1 << " o adding cell gauge for " << libname << endl;
|
|
if (libname == "ibm01") sliceHeight = DbU::lambda(5.04);
|
|
AllianceFramework::get()->addCellGauge (CellGauge::create(libname.c_str(), "METAL2", pitch, sliceHeight, sliceStep));
|
|
//stdCellGauge = cellGauges[libname];
|
|
cmess1 << " o added cell gauge for " << libname << endl;
|
|
}
|
|
//getCDataBase()->setDefaultCellGauge(library->getName());
|
|
|
|
// *****************************************************************************************
|
|
// Check for routing layer gauge
|
|
RoutingGauge* routingGauge = AllianceFramework::get()->getRoutingGauge(library->getName());
|
|
if (!routingGauge) throw Error ("Nimbus : unable to find RoutingGauge associated with library : " +
|
|
getString(library->getName()));
|
|
Fence::setRoutingGauge(Configuration::getDefault()->getCellGauge());
|
|
#endif // CORIOLIS_2_DEPRECATED
|
|
|
|
}
|
|
|
|
|
|
const Name NimbusEngine::_toolName = "Nimbus";
|
|
|
|
NimbusEngine::NimbusEngine (Cell* cell, const Box& workZone)
|
|
// *********************************************************
|
|
: Inherit (cell)
|
|
, _configuration (new Configuration())
|
|
, _depth (0)
|
|
, _placementBoxSet()
|
|
, _routingBoxSet ()
|
|
, _routingLayerSet()
|
|
{
|
|
if ( not workZone.isEmpty() ) _configuration->setWorkZone(workZone);
|
|
}
|
|
|
|
NimbusEngine* NimbusEngine::create (Cell* cell, const Box& workZone)
|
|
// *****************************************************************
|
|
{
|
|
_preCreate(cell);
|
|
|
|
NimbusEngine* nimbus = new NimbusEngine (cell,workZone);
|
|
|
|
nimbus->_postCreate();
|
|
|
|
if ( nimbus->doPinsPlacement() ) nimbus->placePins();
|
|
|
|
return nimbus;
|
|
}
|
|
|
|
void NimbusEngine::_postCreate ()
|
|
// ******************************
|
|
{
|
|
Inherit::_postCreate();
|
|
|
|
// ********************************************************************************************
|
|
// fence display slot creation
|
|
//_displaySlot = DisplaySlot::create (getCell(), "Nimbus::Fences", 255, 0, 0, "FFFFFFFFFFFFFFFF", 1, 0, 255, 0, "CC33CC33CC33CC33", 1);
|
|
|
|
_grid = new Grid ( this );
|
|
|
|
if ( _grid == NULL )
|
|
throw Error ("NimbusEngine was unable to create the grid on <%s>"
|
|
,getString(getCell()->getName()).c_str());
|
|
|
|
getGrid()->getRoot()->setAsPlacementLeaf();
|
|
getGrid()->getRoot()->setAsRoutingLeaf();
|
|
}
|
|
|
|
void NimbusEngine::_preDestroy ()
|
|
// ******************************
|
|
{
|
|
#if 0
|
|
if (_grid)
|
|
delete _grid;
|
|
delete _configuration;
|
|
#endif
|
|
Inherit::_preDestroy();
|
|
}
|
|
|
|
const Name& NimbusEngine::staticGetName()
|
|
// *************************************
|
|
{
|
|
return _toolName;
|
|
}
|
|
|
|
void NimbusEngine::computeXSplit ( GCell* gcell, DbU::Unit* XSplit, unsigned nbSplits )
|
|
// ************************************************************************************
|
|
{
|
|
DbU::Unit X = gcell->getXMin();
|
|
DbU::Unit width = gcell->getWidth();
|
|
unsigned int numColsInf = (unsigned)rint( width / (getPitch() * nbSplits) );
|
|
|
|
// cerr << "computeXSplit(): width:" << DbU::getValueString(width)
|
|
// << " nbsplits:" << nbSplits
|
|
// << " " << (width / getPitch())
|
|
// << " numColsInf:" << numColsInf << endl;
|
|
|
|
if (numColsInf == 0)
|
|
throw Error ("NimbusEngine::computeXSplit(): %s too narrow to be splitted."
|
|
,DbU::getValueString(width).c_str());
|
|
|
|
DbU::Unit splitWidth = numColsInf * getPitch();
|
|
for ( unsigned i = 0 ; i < (nbSplits - 1) ; i++ ) {
|
|
XSplit[i] = X + (i+1) * splitWidth;
|
|
}
|
|
}
|
|
|
|
void NimbusEngine::computeYSplit ( GCell* gcell, DbU::Unit* YSplit, unsigned nbSplits )
|
|
// ************************************************************************************
|
|
{
|
|
DbU::Unit Y = gcell->getYMin();
|
|
DbU::Unit height = gcell->getHeight();
|
|
unsigned int numRowsInf = (unsigned)rint( height / (getSliceHeight() * nbSplits) );
|
|
|
|
if (numRowsInf == 0)
|
|
throw Error ("NimbusEngine::computeYSplit(): %s too narrow to be splitted."
|
|
,DbU::getValueString(height).c_str());
|
|
|
|
DbU::Unit splitHeight = numRowsInf * getSliceHeight();
|
|
for ( unsigned i = 0 ; i < (nbSplits - 1) ; i++ ) {
|
|
YSplit[i] = Y + (i+1) * splitHeight;
|
|
}
|
|
}
|
|
|
|
void NimbusEngine::horizontalLongSplit ( unsigned step, DbU::Unit& Y ) const
|
|
// **************************************************************
|
|
{
|
|
if ( !_grid )
|
|
throw Error ("NimbusEngine ERROR : Can't horizontalLongSplit because no grid exists!");
|
|
|
|
_grid->horizontalLongSplit ( step, Y );
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::verticalLongSplit ( unsigned step, DbU::Unit& X ) const
|
|
// ************************************************************
|
|
{
|
|
if ( !_grid )
|
|
throw Error ("NimbusEngine ERROR : Can't verticalLongSplit because no grid exists!");
|
|
|
|
_grid->verticalLongSplit ( step, X );
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::createFences ( unsigned depth )
|
|
// *****************************************
|
|
{
|
|
if ( !_grid )
|
|
throw Error ("Nimbus ERROR : Can't createFences because no grid exists!");
|
|
_grid->createFences ( depth );
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::placePins()
|
|
// *********************
|
|
{
|
|
UpdateSession::open();
|
|
DbU::Unit width = getCell()->getAbutmentBox().getWidth();
|
|
DbU::Unit height = getCell()->getAbutmentBox().getHeight();
|
|
DbU::Unit xMin = getCell()->getAbutmentBox().getXMin();
|
|
DbU::Unit yMin = getCell()->getAbutmentBox().getYMin();
|
|
|
|
PinIocOrder& northPins = LefDefExtension::getNorthPinIocOrder(getCell());
|
|
PinIocOrder& southPins = LefDefExtension::getSouthPinIocOrder(getCell());
|
|
PinIocOrder& eastPins = LefDefExtension::getEastPinIocOrder(getCell());
|
|
PinIocOrder& westPins = LefDefExtension::getWestPinIocOrder(getCell());
|
|
//PinIocOrder& undefinedPins = LefDefExtension::getUndefinedPinIoc(getCell());
|
|
|
|
unsigned northCount = northPins.size();
|
|
DbU::Unit pos = xMin;
|
|
if (northCount)
|
|
{
|
|
if (width - northCount <= 0)
|
|
throw Error("not enough place on north side");
|
|
|
|
DbU::Unit conSpace = width/northCount;
|
|
pos += conSpace / 2;
|
|
|
|
for (PinIocOrder::iterator pit = northPins.begin();
|
|
pit != northPins.end();
|
|
pit++)
|
|
{
|
|
Pin* pin = getCell()->getPin(*pit);
|
|
if (!pin)
|
|
throw Error("Unknown Pin named : " + getString(*pit));
|
|
pin->setPosition(pos, getCell()->getAbutmentBox().getYMax());
|
|
pos += conSpace;
|
|
}
|
|
}
|
|
|
|
unsigned southCount = southPins.size();
|
|
pos = xMin;
|
|
if (southCount)
|
|
{
|
|
if (width - southCount <= 0)
|
|
throw Error("not enough place on south side");
|
|
|
|
DbU::Unit conSpace = width/southCount;
|
|
pos += conSpace / 2;
|
|
|
|
for (PinIocOrder::iterator pit = southPins.begin();
|
|
pit != southPins.end();
|
|
pit++)
|
|
{
|
|
Pin* pin = getCell()->getPin(*pit);
|
|
if (!pin)
|
|
throw Error("Unknown Pin named : " + getString(*pit));
|
|
pin->setPosition(pos, getCell()->getAbutmentBox().getYMin());
|
|
pos += conSpace;
|
|
}
|
|
}
|
|
|
|
unsigned eastCount = eastPins.size();
|
|
pos = yMin;
|
|
if (eastCount)
|
|
{
|
|
if (height - eastCount <= 0)
|
|
throw Error("not enough place on east side");
|
|
|
|
DbU::Unit conSpace = width/eastCount;
|
|
pos += conSpace / 2;
|
|
|
|
for (PinIocOrder::iterator pit = eastPins.begin();
|
|
pit != eastPins.end();
|
|
pit++)
|
|
{
|
|
Pin* pin = getCell()->getPin(*pit);
|
|
if (!pin)
|
|
throw Error("Unknown Pin named : " + getString(*pit));
|
|
pin->setPosition(getCell()->getAbutmentBox().getXMax(), pos);
|
|
pos += conSpace;
|
|
}
|
|
}
|
|
|
|
unsigned westCount = westPins.size();
|
|
pos = yMin;
|
|
if (westCount)
|
|
{
|
|
if (height - westCount <= 0)
|
|
throw Error("not enough place on west side");
|
|
|
|
DbU::Unit conSpace = width/westCount;
|
|
pos += conSpace / 2;
|
|
for (PinIocOrder::iterator pit = westPins.begin();
|
|
pit != westPins.end();
|
|
pit++)
|
|
{
|
|
Pin* pin = getCell()->getPin(*pit);
|
|
if (!pin)
|
|
throw Error("Unknown Pin named : " + getString(*pit));
|
|
pin->setPosition(getCell()->getAbutmentBox().getYMin(), pos);
|
|
pos += conSpace;
|
|
}
|
|
}
|
|
UpdateSession::close();
|
|
}
|
|
|
|
void NimbusEngine::progress(int nbSplits)
|
|
// ********************************
|
|
{
|
|
progress ( nbSplits, nbSplits );
|
|
}
|
|
|
|
void NimbusEngine::progress(int nbXSplits, int nbYSplits)
|
|
// ************************************************
|
|
{
|
|
if ( ! (nbXSplits > 1) ) throw Error ( "NimbusEngine.progress error must divide into at least 2 gcells on X coordinate" );
|
|
if ( ! (nbYSplits > 1) ) throw Error ( "NimbusEngine.progress error must divide into at least 2 gcells on Y coordinate" );
|
|
|
|
DbU::Unit sliceHeight = getConfiguration()->getSliceHeight();
|
|
for_each_gcell (nb, _grid->getGCells(_depth))
|
|
{
|
|
if (nb->getHeight() == sliceHeight)
|
|
return;
|
|
end_for;
|
|
}
|
|
|
|
GCell* gcell = _grid->getRoot();
|
|
GCell* r = NULL;
|
|
|
|
for (unsigned step = 0 ; step < _depth ; step++) {
|
|
r = gcell->getSubUpperLeft();
|
|
if (!r) {
|
|
gcell->makeSub();
|
|
r = gcell->getSubUpperLeft();
|
|
}
|
|
gcell = r;
|
|
}
|
|
|
|
assert(gcell);
|
|
assert(gcell->getStep() == _depth);
|
|
|
|
_depth++;
|
|
|
|
try {
|
|
|
|
for ( GCell* nby = gcell ; nby != NULL ; nby = _grid->getRightOf (nby) )
|
|
{
|
|
DbU::Unit XSplit [nbXSplits-1];
|
|
computeXSplit ( nby, XSplit, nbXSplits );
|
|
|
|
for ( int i = 0 ; i < (nbXSplits-1) ; i++ ) {
|
|
_grid->verticalLongSplit (_depth, XSplit[i] );
|
|
}
|
|
}
|
|
for ( GCell* nbx = gcell ; nbx != NULL ; nbx = _grid->getDownOf (nbx) )
|
|
{
|
|
DbU::Unit YSplit [nbYSplits-1];
|
|
computeYSplit ( nbx, YSplit, nbYSplits );
|
|
|
|
for ( int i = 0 ; i < (nbYSplits-1) ; i++ ) {
|
|
_grid->horizontalLongSplit ( _depth, YSplit[i] );
|
|
}
|
|
}
|
|
|
|
|
|
_grid->createFences(_depth);
|
|
|
|
} catch (Hurricane::Error &e) {
|
|
if (e.getCode() != 1) throw e;
|
|
cmess1 << "[WARNING] Finest grid level reached" << endl;
|
|
destroyLevel(_depth);
|
|
}
|
|
}
|
|
|
|
void NimbusEngine::recDestroy(unsigned depth, GCell* gcell)
|
|
{
|
|
if (gcell->getDepth() == depth) gcell->destroy();
|
|
else for_each_gcell(subgcell, gcell->getSubGCells())
|
|
{
|
|
recDestroy(depth, subgcell);
|
|
end_for;
|
|
}
|
|
}
|
|
|
|
void NimbusEngine::destroyLevel(unsigned depth)
|
|
{
|
|
recDestroy (depth, getGrid()->getRoot());
|
|
if (depth > 0) _depth = depth - 1;
|
|
}
|
|
|
|
#if 0
|
|
void NimbusEngine::balanceLeaves()
|
|
{
|
|
GCell* CornerRB = _grid->getUpperLeftCorner(_step);
|
|
|
|
|
|
// Balancing columns
|
|
// *****************
|
|
{
|
|
GCell* col1RB = CornerRB;
|
|
GCell* col2RB = NULL;
|
|
|
|
while (col1RB)
|
|
{
|
|
col2RB = col1RB->getRightOfMe();
|
|
assert (col2RB);
|
|
GCell* nb1 = col1RB;
|
|
GCell* nb2 = col2RB;
|
|
|
|
// Cell surface & width summation
|
|
// ******************************
|
|
while (nb1 != NULL)
|
|
{
|
|
assert (nb2 != NULL);
|
|
cumulatedSurface1 += getCellsSurface (nb1);
|
|
cumulatedSurface2 += getCellsSurface (nb2);
|
|
cumulatedWidth1 += getCellsWidth (nb1);
|
|
cumulatedWidth2 += getCellsWidth (nb2);
|
|
nb1 = nb1->getDownOfMe();
|
|
nb2 = nb2->getDownOfMe();
|
|
}
|
|
|
|
// Tuning the vertical cut line
|
|
// ****************************
|
|
|
|
|
|
// Onto the next column pair
|
|
// *************************
|
|
col1RB = col2RB->getRightOfMe();
|
|
}
|
|
}
|
|
|
|
// Balancing rows
|
|
// **************
|
|
{
|
|
GCell* row1RB = CornerRB;
|
|
GCell* row2RB = NULL;
|
|
|
|
while (row1RB)
|
|
{
|
|
row2RB = row1RB->getDownOfMe();
|
|
assert (row2RB);
|
|
GCell* nb1 = row1RB;
|
|
GCell* nb2 = row2RB;
|
|
|
|
// Cell surface & height summation
|
|
// *******************************
|
|
while (nb1 != NULL)
|
|
{
|
|
assert (nb2 != NULL);
|
|
cumulatedSurface1 += getCellsSurface (nb1);
|
|
cumulatedSurface2 += getCellsSurface (nb2);
|
|
cumulatedHeight1 += getCellsHeight (nb1);
|
|
cumulatedHeight2 += getCellsHeight (nb2);
|
|
nb1 = nb1->getRightOfMe();
|
|
nb2 = nb2->getRightOfMe();
|
|
}
|
|
|
|
// Tuning the horizontal cut line
|
|
// ******************************
|
|
|
|
|
|
// Onto the next row pair
|
|
// **********************
|
|
row1RB = row2RB->getDownOfMe();
|
|
}
|
|
}
|
|
|
|
// Balancing finished
|
|
|
|
return;
|
|
} // balanceLeaves
|
|
#endif
|
|
|
|
#if 0
|
|
DbU::Unit NimbusEngine::getStandardCellHeight () const
|
|
// ****************************************
|
|
{
|
|
return _stdCellHeight;
|
|
}
|
|
#endif
|
|
|
|
GCell* NimbusEngine::getPlacementLeafContaining(Point& p)
|
|
// *************************************************
|
|
{
|
|
GCell* gcell = getGrid()->getRoot();
|
|
|
|
while (! (gcell->isAPlacementLeaf()) )
|
|
{
|
|
bool deeper = false;
|
|
for_each_gcell (nb, gcell->getSubGCells())
|
|
{
|
|
if (nb->strictContains(p))
|
|
{
|
|
gcell = nb;
|
|
deeper = true;
|
|
}
|
|
end_for;
|
|
}
|
|
if (!deeper) return NULL;
|
|
}
|
|
return gcell;
|
|
}
|
|
|
|
bool NimbusEngine::testMargin ( double margin )
|
|
// **************************************
|
|
{
|
|
bool testOK = true;
|
|
for_each_gcell ( gcell, getPlacementLeaves() )
|
|
{
|
|
string message = " - GCell " + getString( gcell ) + " :\t";
|
|
double NimbMargin = gcell->testMargin();
|
|
if ( NimbMargin < 0 )
|
|
{
|
|
message += "negative margin = " + getString ( NimbMargin );
|
|
testOK = false;
|
|
}
|
|
else if ( NimbMargin < margin )
|
|
{
|
|
message += "margin = " + getString ( NimbMargin ) + " < " + getString ( margin );
|
|
testOK = false;
|
|
}
|
|
else
|
|
{
|
|
message += "margin = " + getString ( NimbMargin ) + " : OK";
|
|
}
|
|
cmess1 << message << endl;
|
|
end_for;
|
|
}
|
|
|
|
return testOK;
|
|
}
|
|
|
|
bool NimbusEngine::testMargin ()
|
|
// *****************************
|
|
{
|
|
bool testOK = true;
|
|
for_each_gcell ( gcell, getPlacementLeaves() )
|
|
{
|
|
string message = " - GCell " + getString( gcell ) + " :\t";
|
|
double NimbMargin = gcell->testMargin();
|
|
if ( NimbMargin < 0 )
|
|
{
|
|
message += "negative margin = " + getString ( NimbMargin );
|
|
testOK = false;
|
|
}
|
|
else if ( NimbMargin < getMargin() )
|
|
{
|
|
message += "margin = " + getString ( NimbMargin ) + " < " + getString ( getMargin() );
|
|
testOK = false;
|
|
}
|
|
else
|
|
{
|
|
message += "margin = " + getString ( NimbMargin ) + " : OK";
|
|
}
|
|
cmess1 << message << endl;
|
|
end_for;
|
|
}
|
|
|
|
return testOK;
|
|
}
|
|
|
|
GCell* NimbusEngine::getRoutingLeafContaining(Point& p)
|
|
// ***********************************************
|
|
{
|
|
GCell* gcell = getGrid()->getRoot();
|
|
|
|
while (! (gcell->isARoutingLeaf()) )
|
|
{
|
|
bool deeper = false;
|
|
for_each_gcell (nb, gcell->getSubGCells())
|
|
{
|
|
if (nb->strictContains(p))
|
|
{
|
|
gcell = nb;
|
|
deeper = true;
|
|
}
|
|
end_for;
|
|
}
|
|
if (!deeper) return NULL;
|
|
}
|
|
return gcell;
|
|
}
|
|
|
|
|
|
GCell* NimbusEngine::getCommonAncester(GCell* nb1, GCell* nb2) const
|
|
// **************************************************************
|
|
{
|
|
if (nb1 == nb2) return nb1;
|
|
|
|
if (!nb1) return nb2;
|
|
if (!nb2) return nb1;
|
|
|
|
if (nb1->getStep() > nb2->getStep())
|
|
return getCommonAncester(nb1->getContainer(), nb2);
|
|
else
|
|
return getCommonAncester(nb1, nb2->getContainer());
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
GCells NimbusEngine::getLeaves() const
|
|
// *************************
|
|
{
|
|
return _grid->getGCells(_depth);
|
|
}
|
|
GCells NimbusEngine::getLeaves(unsigned step) const
|
|
// **************************************
|
|
{
|
|
if (step > _depth) throw ("[ERROR] Request for an unreached refinement level");
|
|
|
|
return _grid->getFastGCells(step);
|
|
}
|
|
|
|
Fences NimbusEngine::getFences(unsigned step)
|
|
// ************************************
|
|
{
|
|
if (step > _depth) throw ("[ERROR] Request for an unreached refinement level");
|
|
|
|
return (_grid->getFences(step));
|
|
}
|
|
|
|
GCells NimbusEngine::getPlacementLeaves() const
|
|
// ****************************************
|
|
{
|
|
return Nimbus_GCells(&_placementBoxSet);
|
|
}
|
|
|
|
GCells NimbusEngine::getRoutingLeaves() const
|
|
// **************************************
|
|
{
|
|
return Nimbus_GCells(&_routingBoxSet);
|
|
}
|
|
|
|
Fences NimbusEngine::getRoutingFences() const
|
|
// ************************************
|
|
{
|
|
return Nimbus_Fences(&_routingFenceSet);
|
|
}
|
|
|
|
GCells NimbusEngine::getColumnGCells( unsigned indexColumn ) const
|
|
// *************************************************************
|
|
{
|
|
GCell* _upperGCell = ((NimbusEngine*)this)->getGrid()->getUpperLeftCorner(((NimbusEngine*)this)->getDepth()); //(Nimbus*)this to avoid const problem
|
|
for ( unsigned i = indexColumn ; i > 0 ; i-- ) {
|
|
_upperGCell = _upperGCell->getRightOfMe();
|
|
if (!_upperGCell)
|
|
throw Error ( "NimbusEngine: Invalid Column Index" );
|
|
}
|
|
return Nimbus_ColumnGCells(_upperGCell);
|
|
}
|
|
|
|
GCells NimbusEngine::getRowGCells( unsigned indexRow ) const
|
|
// *******************************************************
|
|
{
|
|
GCell* _leftGCell = ((NimbusEngine*)this)->getGrid()->getUpperLeftCorner(((NimbusEngine*)this)->getDepth()); //(Nimbus*)this to avoid const problem
|
|
for ( unsigned i = indexRow ; i > 0 ; i-- ) {
|
|
_leftGCell = _leftGCell->getDownOfMe();
|
|
if (!_leftGCell)
|
|
throw Error ( "NimbusEngine: Invalid Row Index" );
|
|
}
|
|
|
|
return Nimbus_RowGCells(_leftGCell);
|
|
}
|
|
|
|
Layers NimbusEngine::getRoutingLayers() const
|
|
// ************************************
|
|
{
|
|
return Nimbus_Layers(&_routingLayerSet);
|
|
}
|
|
|
|
void NimbusEngine::flushRoutingFences()
|
|
// ******************************
|
|
{
|
|
for_each_fence(fence, getRoutingFences())
|
|
{
|
|
fence->_NotRoutingFence();
|
|
end_for;
|
|
}
|
|
_routingFenceSet.clear();
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::addToRoutingFences(Fence* fence)
|
|
// ******************************************
|
|
{
|
|
_routingFenceSet.insert(fence);
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::addToRoutingLayers(Layer* layer)
|
|
// ******************************************
|
|
{
|
|
_routingLayerSet.insert(layer);
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::flushPlacementLeaves()
|
|
// ******************************
|
|
{
|
|
for_each_gcell(gcell, getPlacementLeaves())
|
|
{
|
|
gcell->_setNotPlacementLeaf();
|
|
end_for;
|
|
}
|
|
_placementBoxSet.clear();
|
|
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::flushRoutingLeaves()
|
|
// ******************************
|
|
{
|
|
for_each_gcell(gcell, getRoutingLeaves())
|
|
{
|
|
gcell->_setNotRoutingLeaf();
|
|
end_for;
|
|
}
|
|
_routingBoxSet.clear();
|
|
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::setRoutingLeaf(GCell* gcell)
|
|
// ****************************************
|
|
{
|
|
setLeaf(gcell, _routingBoxSet);
|
|
return;
|
|
}
|
|
void NimbusEngine::setPlacementLeaf(GCell* gcell)
|
|
// ******************************************
|
|
{
|
|
setLeaf(gcell, _placementBoxSet);
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::setSubGCellsAsPlacementLeaves (GCell* gcell)
|
|
// **********************************************************
|
|
{
|
|
gcell->setSubGCellsAsPlacementLeaves();
|
|
return;
|
|
}
|
|
void NimbusEngine::setSubGCellsAsRoutingLeaves (GCell* gcell)
|
|
// ********************************************************
|
|
{
|
|
gcell->setSubGCellsAsRoutingLeaves();
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::setLeaf(GCell* gcell, GCellSet& nbset)
|
|
// ***************************************************
|
|
{
|
|
nbset.insert(gcell);
|
|
#if 0
|
|
GCell* container = gcell->getContainer();
|
|
while (container)
|
|
{
|
|
GCellSet::iterator nbit = nbset.find(container);
|
|
if (nbit != nbset.end())
|
|
nbset.erase(nbit);
|
|
container = container->getContainer();
|
|
}
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::_removePlacementLeaf(GCell* gcell)
|
|
// **********************************************
|
|
{
|
|
GCellSet::iterator nbit = _placementBoxSet.find(gcell);
|
|
if (nbit != _placementBoxSet.end())
|
|
_placementBoxSet.erase(nbit);
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::_removeRoutingLeaf(GCell* gcell)
|
|
// **********************************************
|
|
{
|
|
GCellSet::iterator nbit = _routingBoxSet.find(gcell);
|
|
if (nbit != _routingBoxSet.end())
|
|
_routingBoxSet.erase(nbit);
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::regroup(bool placed, bool fixed)
|
|
// *****************
|
|
{
|
|
grabPlacementModificationFlag();
|
|
UpdateSession::open();
|
|
for_each_instance(ins, getCell()->getInstances())
|
|
{
|
|
if ( (ins->getPlacementStatus() == Instance::PlacementStatus::PLACED) && !placed ) continue;
|
|
if ( (ins->getPlacementStatus() == Instance::PlacementStatus::FIXED ) && !fixed ) continue;
|
|
|
|
Box instanceABox = ins->getAbutmentBox();
|
|
Point insCenter = ins->getBoundingBox().getCenter();
|
|
GCell* nb = getPlacementLeafContaining(insCenter);
|
|
if ( nb )
|
|
{
|
|
Point center = nb->getCenter();
|
|
DbU::Unit xPos = center.getX();
|
|
DbU::Unit yPos = center.getY();
|
|
Box masterABox = ins->getMasterCell()->getAbutmentBox();
|
|
ins->setTransformation(
|
|
getTransformation(
|
|
masterABox,
|
|
xPos - instanceABox.getHalfWidth(),
|
|
yPos - instanceABox.getHalfHeight(),
|
|
Transformation::Orientation::ID)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
cerr << "Didn't find PlacementLeaf for instance " << ins << endl;
|
|
}
|
|
end_for;
|
|
}
|
|
UpdateSession::close();
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::placementLeavesUp ()
|
|
// ******************************
|
|
{
|
|
UpdateSession::open();
|
|
grabPlacementModificationFlag();
|
|
set<GCell*> gcelles;
|
|
set<GCell*> newleaves;
|
|
getPlacementLeaves().fill(gcelles);
|
|
|
|
for_each_gcell (gcell, getPlacementLeaves())
|
|
{
|
|
GCell* container = gcell->getContainer();
|
|
if (container) gcelles.insert (container);
|
|
end_for;
|
|
}
|
|
|
|
for(set<GCell*>::iterator nbit = gcelles.begin() ; nbit != gcelles.end() ; nbit++)
|
|
{
|
|
GCell* nb1 = *nbit;
|
|
GCell* nb2 = *nbit;
|
|
bool found (false);
|
|
while ( (nb2 = nb2->getContainer()) )
|
|
{
|
|
if ( gcelles.find (nb2) != gcelles.end() )
|
|
found = true;
|
|
}
|
|
if (!found) newleaves.insert (nb1);
|
|
}
|
|
|
|
for(set<GCell*>::iterator nbit = newleaves.begin() ; nbit != newleaves.end() ; nbit++)
|
|
{
|
|
GCell* nb = *nbit;
|
|
nb->setAsPlacementLeaf();
|
|
}
|
|
|
|
hideFences();
|
|
showPlacementLeaves();
|
|
UpdateSession::close();
|
|
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::placementLeavesDown ()
|
|
// ******************************
|
|
{
|
|
UpdateSession::open();
|
|
grabPlacementModificationFlag();
|
|
set<GCell*> gcelles;
|
|
getPlacementLeaves().fill(gcelles);
|
|
for(set<GCell*>::iterator nbit = gcelles.begin() ; nbit != gcelles.end() ; nbit++)
|
|
{
|
|
(*nbit)->setSubGCellsAsPlacementLeaves();
|
|
}
|
|
hideFences();
|
|
showPlacementLeaves();
|
|
UpdateSession::close();
|
|
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::hideFences()
|
|
// **********************
|
|
{
|
|
for (unsigned step = 1; step <= _depth ; step++)
|
|
{
|
|
for_each_fence (fence, getFences(step))
|
|
{
|
|
fence->setInvisible();
|
|
end_for;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::showPlacementLeaves()
|
|
// *******************************
|
|
{
|
|
for_each_gcell(gcell, getPlacementLeaves())
|
|
{
|
|
for_each_fence(fence, gcell->getSurroundingFences())
|
|
{
|
|
fence->setVisible();
|
|
end_for;
|
|
}
|
|
end_for;
|
|
}
|
|
for_each_go(go, getCell()->getExtensionSlice("Nimbus::Grid")->_getQuadTree()->getGos())
|
|
{
|
|
Fence* fence (NULL);
|
|
if (! (fence = (dynamic_cast<Fence*> (go)) ) ) continue;
|
|
if (! fence->isVisible() ) continue;
|
|
Fence* pfence (fence);
|
|
while ( (pfence = pfence->getParentFence()) ) pfence->setInvisible();
|
|
end_for;
|
|
}
|
|
|
|
return;
|
|
}
|
|
void NimbusEngine::showRoutingLeaves()
|
|
// *******************************
|
|
{
|
|
for_each_gcell(gcell, getRoutingLeaves())
|
|
{
|
|
for_each_fence(fence, gcell->getSurroundingFences())
|
|
{
|
|
fence->setVisible();
|
|
end_for;
|
|
}
|
|
end_for;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::invalidateSplitterContactsOppositeCounts(Net* net)
|
|
// ************************************************************
|
|
{
|
|
assert(net);
|
|
for_each_component(compo, net->getComponents())
|
|
{
|
|
if (! (dynamic_cast<SplitterContact*> (compo)) )
|
|
continue;
|
|
SplitterContact* sc = dynamic_cast<SplitterContact*> (compo);
|
|
sc->invalidateOppositeCounts();
|
|
end_for;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void NimbusEngine::invalidateSplitterContactsOppositeCounts()
|
|
// ****************************************************
|
|
{
|
|
for_each_net(net, getCell()->getNets())
|
|
{
|
|
invalidateSplitterContactsOppositeCounts(net);
|
|
end_for;
|
|
}
|
|
return;
|
|
}
|
|
|
|
string NimbusEngine::_getString() const
|
|
// ******************************
|
|
{
|
|
return "<" + _TName("Nimbus") + ">";
|
|
}
|
|
|
|
Record* NimbusEngine::_getRecord() const
|
|
// *************************
|
|
{
|
|
Record* record = Inherit::_getRecord();
|
|
|
|
if (record) {
|
|
record->add(getSlot("Depth", _depth));
|
|
record->add(getSlot("Root Box", _grid->getRoot()));
|
|
}
|
|
return record;
|
|
}
|
|
|
|
const Name& NimbusEngine::getName () const
|
|
{
|
|
return _toolName;
|
|
}
|
|
|
|
|
|
|
|
NimbusEngine* NimbusEngine::get ( Cell* cell )
|
|
{
|
|
return static_cast<NimbusEngine*>(ToolEngine::get(cell, staticGetName()));
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_GCells implementation
|
|
*
|
|
*/
|
|
|
|
Nimbus_GCells::Nimbus_GCells(const GCellSet* nbset)
|
|
// **************************************************************************************
|
|
: Inherit()
|
|
, _nbset(nbset)
|
|
{
|
|
assert(nbset);
|
|
_nbit = nbset->begin();
|
|
}
|
|
|
|
Nimbus_GCells::Nimbus_GCells(const Nimbus_GCells& gcelles)
|
|
// ************************************************************************************
|
|
: Inherit()
|
|
, _nbset(gcelles._nbset)
|
|
, _nbit(gcelles._nbit)
|
|
{
|
|
}
|
|
|
|
Nimbus_GCells& Nimbus_GCells::operator=(const Nimbus_GCells& gcelles)
|
|
// ****************************************************************
|
|
{
|
|
_nbset = gcelles._nbset;
|
|
_nbit = gcelles._nbit;
|
|
return *this;
|
|
}
|
|
|
|
Collection<GCell*>* Nimbus_GCells::getClone() const
|
|
// ***********************************************
|
|
{
|
|
return new Nimbus_GCells(*this);
|
|
}
|
|
|
|
Locator<GCell*>* Nimbus_GCells::getLocator() const
|
|
// **********************************************
|
|
{
|
|
return new Locator(_nbset, _nbit);
|
|
}
|
|
|
|
string Nimbus_GCells::_getString() const
|
|
// *************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::GCells");
|
|
//if (_gcellIterator) s += " " + getString((*_gcellIterator));
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_GCells::Locator implementation
|
|
*/
|
|
Nimbus_GCells::Locator::Locator(const GCellSet* nbset, GCellSet::iterator nbit)
|
|
// ************************************************************************************
|
|
: Inherit(),
|
|
_nbset(nbset),
|
|
_nbit(nbit)
|
|
{
|
|
}
|
|
|
|
Nimbus_GCells::Locator::Locator(const Locator& locator)
|
|
// ****************************************************
|
|
: Inherit(),
|
|
_nbset(locator._nbset),
|
|
_nbit(locator._nbit)
|
|
{
|
|
}
|
|
|
|
Nimbus_GCells::Locator& Nimbus_GCells::Locator::operator=(const Locator& locator)
|
|
// ******************************************************************************
|
|
{
|
|
_nbset = locator._nbset;
|
|
_nbit = locator._nbit;
|
|
return *this;
|
|
}
|
|
|
|
GCell* Nimbus_GCells::Locator::getElement() const
|
|
// **************************************************
|
|
{
|
|
return (*_nbit);
|
|
}
|
|
|
|
Locator<GCell*>* Nimbus_GCells::Locator::getClone() const
|
|
// *****************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Nimbus_GCells::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return (_nbit != _nbset->end());
|
|
}
|
|
|
|
void Nimbus_GCells::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
_nbit++;
|
|
|
|
return;
|
|
}
|
|
|
|
string Nimbus_GCells::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::GCells::Locator");
|
|
if (_nbit != _nbset->end()) s += " " + getString(*_nbit);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_ColumnGCells implementation
|
|
*
|
|
*/
|
|
|
|
Nimbus_ColumnGCells::Nimbus_ColumnGCells(const GCell* upperGCell)
|
|
// *********************************************************************
|
|
: Inherit(),
|
|
_upperGCell ( upperGCell )
|
|
{
|
|
}
|
|
|
|
Nimbus_ColumnGCells::Nimbus_ColumnGCells(const Nimbus_ColumnGCells& gcelles)
|
|
// ********************************************************************************
|
|
: Inherit()
|
|
{
|
|
_upperGCell = gcelles._upperGCell;
|
|
}
|
|
|
|
Nimbus_ColumnGCells& Nimbus_ColumnGCells::operator=(const Nimbus_ColumnGCells& gcelles)
|
|
// *******************************************************************************************
|
|
{
|
|
_upperGCell = gcelles._upperGCell;
|
|
return *this;
|
|
}
|
|
|
|
Collection<GCell*>* Nimbus_ColumnGCells::getClone() const
|
|
// *********************************************************
|
|
{
|
|
return new Nimbus_ColumnGCells(*this);
|
|
}
|
|
|
|
Locator<GCell*>* Nimbus_ColumnGCells::getLocator() const
|
|
// **********************************************
|
|
{
|
|
return new Locator(_upperGCell);
|
|
}
|
|
|
|
string Nimbus_ColumnGCells::_getString() const
|
|
// *********************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::ColumnGCells");
|
|
//if (_gcellIterator) s += " " + getString((*_gcellIterator));
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_ColumnGCells::Locator implementation
|
|
*/
|
|
Nimbus_ColumnGCells::Locator::Locator(const GCell* gcell)
|
|
// **********************************************************
|
|
: Inherit(),
|
|
_gcell(gcell)
|
|
{
|
|
}
|
|
|
|
Nimbus_ColumnGCells::Locator::Locator(const Locator& locator)
|
|
// ************************************************************
|
|
: Inherit(),
|
|
_gcell(locator._gcell)
|
|
{
|
|
}
|
|
|
|
Nimbus_ColumnGCells::Locator& Nimbus_ColumnGCells::Locator::operator=(const Locator& locator)
|
|
// **********************************************************************************************
|
|
{
|
|
_gcell = locator._gcell;
|
|
return *this;
|
|
}
|
|
|
|
GCell* Nimbus_ColumnGCells::Locator::getElement() const
|
|
// *******************************************************
|
|
{
|
|
return (GCell*)_gcell;
|
|
}
|
|
|
|
Locator<GCell*>* Nimbus_ColumnGCells::Locator::getClone() const
|
|
// ***************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Nimbus_ColumnGCells::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return (_gcell != NULL);
|
|
}
|
|
|
|
void Nimbus_ColumnGCells::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
_gcell = _gcell->getDownOfMe();
|
|
return;
|
|
}
|
|
|
|
string Nimbus_ColumnGCells::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::ColumnGCells::Locator");
|
|
s += " " + getString(_gcell);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_RowGCells implementation
|
|
*
|
|
*/
|
|
|
|
Nimbus_RowGCells::Nimbus_RowGCells(const GCell* leftGCell)
|
|
// *************************************************************
|
|
: Inherit(),
|
|
_leftGCell ( leftGCell )
|
|
{
|
|
}
|
|
|
|
Nimbus_RowGCells::Nimbus_RowGCells(const Nimbus_RowGCells& gcelles)
|
|
// ***********************************************************************
|
|
: Inherit()
|
|
{
|
|
_leftGCell = gcelles._leftGCell;
|
|
}
|
|
|
|
Nimbus_RowGCells& Nimbus_RowGCells::operator=(const Nimbus_RowGCells& gcelles)
|
|
// *******************************************************************************************
|
|
{
|
|
_leftGCell = gcelles._leftGCell;
|
|
return *this;
|
|
}
|
|
|
|
Collection<GCell*>* Nimbus_RowGCells::getClone() const
|
|
// ******************************************************
|
|
{
|
|
return new Nimbus_RowGCells(*this);
|
|
}
|
|
|
|
Locator<GCell*>* Nimbus_RowGCells::getLocator() const
|
|
// *****************************************************
|
|
{
|
|
return new Locator(_leftGCell);
|
|
}
|
|
|
|
string Nimbus_RowGCells::_getString() const
|
|
// ******************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::RowGCells");
|
|
//if (_gcellIterator) s += " " + getString((*_gcellIterator));
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_RowGCells::Locator implementation
|
|
*/
|
|
Nimbus_RowGCells::Locator::Locator(const GCell* gcell)
|
|
// *******************************************************
|
|
: Inherit(),
|
|
_gcell(gcell)
|
|
{
|
|
}
|
|
|
|
Nimbus_RowGCells::Locator::Locator(const Locator& locator)
|
|
// *********************************************************
|
|
: Inherit(),
|
|
_gcell(locator._gcell)
|
|
{
|
|
}
|
|
|
|
Nimbus_RowGCells::Locator& Nimbus_RowGCells::Locator::operator=(const Locator& locator)
|
|
// ****************************************************************************************
|
|
{
|
|
_gcell = locator._gcell;
|
|
return *this;
|
|
}
|
|
|
|
GCell* Nimbus_RowGCells::Locator::getElement() const
|
|
// ****************************************************
|
|
{
|
|
return (GCell*)_gcell;
|
|
}
|
|
|
|
Locator<GCell*>* Nimbus_RowGCells::Locator::getClone() const
|
|
// ************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Nimbus_RowGCells::Locator::isValid() const
|
|
// **********************************************
|
|
{
|
|
return (_gcell != NULL);
|
|
}
|
|
|
|
void Nimbus_RowGCells::Locator::progress()
|
|
// *****************************************
|
|
{
|
|
_gcell = _gcell->getRightOfMe();
|
|
return;
|
|
}
|
|
|
|
string Nimbus_RowGCells::Locator::_getString() const
|
|
// ***************************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::RowGCells::Locator");
|
|
s += " " + getString(_gcell);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_Fences implementation
|
|
*
|
|
*/
|
|
|
|
Nimbus_Fences::Nimbus_Fences(const FenceSet* fcset)
|
|
// **************************************************************************************
|
|
: Inherit()
|
|
, _fcset(fcset)
|
|
{
|
|
assert(fcset);
|
|
_fcit = fcset->begin();
|
|
}
|
|
|
|
Nimbus_Fences::Nimbus_Fences(const Nimbus_Fences& fences)
|
|
// ************************************************************************************
|
|
: Inherit()
|
|
, _fcset(fences._fcset)
|
|
, _fcit(fences._fcit)
|
|
{
|
|
}
|
|
|
|
Nimbus_Fences& Nimbus_Fences::operator=(const Nimbus_Fences& fences)
|
|
// ****************************************************************
|
|
{
|
|
_fcset = fences._fcset;
|
|
_fcit = fences._fcit;
|
|
return *this;
|
|
}
|
|
|
|
Collection<Fence*>* Nimbus_Fences::getClone() const
|
|
// ***********************************************
|
|
{
|
|
return new Nimbus_Fences(*this);
|
|
}
|
|
|
|
Locator<Fence*>* Nimbus_Fences::getLocator() const
|
|
// **********************************************
|
|
{
|
|
return new Locator(_fcset, _fcit);
|
|
}
|
|
|
|
string Nimbus_Fences::_getString() const
|
|
// *************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::Fences");
|
|
//if (_fenceIterator) s += " " + getString((*_fenceIterator));
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_Fences::Locator implementation
|
|
*/
|
|
Nimbus_Fences::Locator::Locator(const FenceSet* fcset, FenceSet::iterator fcit)
|
|
// ************************************************************************************
|
|
: Inherit(),
|
|
_fcset(fcset),
|
|
_fcit(fcit)
|
|
{
|
|
}
|
|
|
|
Nimbus_Fences::Locator::Locator(const Locator& locator)
|
|
// ****************************************************
|
|
: Inherit(),
|
|
_fcset(locator._fcset),
|
|
_fcit(locator._fcit)
|
|
{
|
|
}
|
|
|
|
Nimbus_Fences::Locator& Nimbus_Fences::Locator::operator=(const Locator& locator)
|
|
// ******************************************************************************
|
|
{
|
|
_fcset = locator._fcset;
|
|
_fcit = locator._fcit;
|
|
return *this;
|
|
}
|
|
|
|
Fence* Nimbus_Fences::Locator::getElement() const
|
|
// **************************************************
|
|
{
|
|
return (*_fcit);
|
|
}
|
|
|
|
Locator<Fence*>* Nimbus_Fences::Locator::getClone() const
|
|
// *****************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Nimbus_Fences::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return (_fcit != _fcset->end());
|
|
}
|
|
|
|
void Nimbus_Fences::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
_fcit++;
|
|
|
|
return;
|
|
}
|
|
|
|
string Nimbus_Fences::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::Fences::Locator");
|
|
if (_fcit != _fcset->end()) s += " " + getString(*_fcit);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_Layers implementation
|
|
*
|
|
*/
|
|
|
|
Nimbus_Layers::Nimbus_Layers(const set<Layer*>* lset)
|
|
// **************************************************************************************
|
|
: Inherit()
|
|
, _lset(lset)
|
|
{
|
|
assert(lset);
|
|
_lit = lset->begin();
|
|
}
|
|
|
|
Nimbus_Layers::Nimbus_Layers(const Nimbus_Layers& layers)
|
|
// ************************************************************************************
|
|
: Inherit()
|
|
, _lset(layers._lset)
|
|
, _lit(layers._lit)
|
|
{
|
|
}
|
|
|
|
Nimbus_Layers& Nimbus_Layers::operator=(const Nimbus_Layers& layers)
|
|
// ****************************************************************
|
|
{
|
|
_lset = layers._lset;
|
|
_lit = layers._lit;
|
|
return *this;
|
|
}
|
|
|
|
Collection<Layer*>* Nimbus_Layers::getClone() const
|
|
// ***********************************************
|
|
{
|
|
return new Nimbus_Layers(*this);
|
|
}
|
|
|
|
Locator<Layer*>* Nimbus_Layers::getLocator() const
|
|
// **********************************************
|
|
{
|
|
return new Locator(_lset, _lit);
|
|
}
|
|
|
|
string Nimbus_Layers::_getString() const
|
|
// *************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::Layers");
|
|
//if (_layerIterator) s += " " + getString((*_layerIterator));
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Nimbus_Layers::Locator implementation
|
|
*/
|
|
Nimbus_Layers::Locator::Locator(const set<Layer*>* lset, set<Layer*>::iterator lit)
|
|
// ************************************************************************************
|
|
: Inherit(),
|
|
_lset(lset),
|
|
_lit(lit)
|
|
{
|
|
}
|
|
|
|
Nimbus_Layers::Locator::Locator(const Locator& locator)
|
|
// ****************************************************
|
|
: Inherit(),
|
|
_lset(locator._lset),
|
|
_lit(locator._lit)
|
|
{
|
|
}
|
|
|
|
Nimbus_Layers::Locator& Nimbus_Layers::Locator::operator=(const Locator& locator)
|
|
// ******************************************************************************
|
|
{
|
|
_lset = locator._lset;
|
|
_lit = locator._lit;
|
|
return *this;
|
|
}
|
|
|
|
Layer* Nimbus_Layers::Locator::getElement() const
|
|
// **************************************************
|
|
{
|
|
return (*_lit);
|
|
}
|
|
|
|
Locator<Layer*>* Nimbus_Layers::Locator::getClone() const
|
|
// *****************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Nimbus_Layers::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return (_lit != _lset->end());
|
|
}
|
|
|
|
void Nimbus_Layers::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
_lit++;
|
|
|
|
return;
|
|
}
|
|
|
|
string Nimbus_Layers::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Nimbus::Layers::Locator");
|
|
if (_lit != _lset->end()) s += " " + getString(*_lit);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Nimbus
|