736 lines
18 KiB
C++
736 lines
18 KiB
C++
|
|
// This file is part of the Coriolis Project.
|
|
// Copyright (C) Laboratoire LIP6 - Departement ASIM
|
|
// Universite Pierre et Marie Curie
|
|
//
|
|
// Date : 29/01/2004
|
|
// Author : Hugo Clément <Hugo.Clement@lip6.fr>
|
|
|
|
|
|
#include "nimbus/NimbusEngine.h"
|
|
|
|
|
|
namespace Nimbus {
|
|
|
|
|
|
using namespace std;
|
|
|
|
const Name Fence::_extensionName = "Nimbus::Grid";
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence_Splitters declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Fence_Splitters : public Collection<Splitter*> {
|
|
|
|
public: typedef Collection<Splitter*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<Splitter*> {
|
|
|
|
public: typedef Hurricane::Locator<Splitter*> Inherit;
|
|
|
|
private: const SplitterSet* _spset;
|
|
private: SplitterSet::iterator _spit;
|
|
|
|
public: Locator(const SplitterSet* spset, SplitterSet::iterator spit);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual Splitter* getElement() const;
|
|
public: virtual Hurricane::Locator<Splitter*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
private: const SplitterSet* _spset;
|
|
private: SplitterSet::iterator _spit;
|
|
|
|
public: Fence_Splitters(const SplitterSet* spset);
|
|
public: Fence_Splitters(const Fence_Splitters& splitters);
|
|
|
|
public: Fence_Splitters& operator=(const Fence_Splitters& splitters);
|
|
|
|
public: virtual Collection<Splitter*>* getClone() const;
|
|
public: virtual Hurricane::Locator<Splitter*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence_GCells declaration
|
|
* ********************************************************************
|
|
*/
|
|
class Fence_GCells : public Collection<GCell*> {
|
|
|
|
public: typedef Collection<GCell*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<GCell*> {
|
|
|
|
public: typedef Hurricane::Locator<GCell*> Inherit;
|
|
|
|
private: const Fence* _fence;
|
|
private: GCell* _gc;
|
|
|
|
public: Locator(const Fence* fence, GCell* gcell = NULL);
|
|
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 Fence* _fence;
|
|
private: GCell* _gc;
|
|
|
|
public: Fence_GCells(const Fence* fence);
|
|
public: Fence_GCells(const Fence_GCells& gcelles);
|
|
|
|
public: Fence_GCells& operator=(const Fence_GCells& gcelles);
|
|
|
|
public: virtual Collection<GCell*>* getClone() const;
|
|
public: virtual Hurricane::Locator<GCell*>* getLocator() const;
|
|
|
|
public: virtual string _getString() const;
|
|
};
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence implementation
|
|
*
|
|
*/
|
|
|
|
|
|
Fence::Fence ( Grid* grid, DbU::Unit size, unsigned capacity, unsigned occupancy, bool visible)
|
|
: Inherit (grid->getCell())
|
|
, _splitters ()
|
|
, _components ()
|
|
, _occupancy (occupancy)
|
|
, _capacity (capacity)
|
|
, _frontLine (NULL)
|
|
, _nextOfFenceSubFenceSet(NULL)
|
|
, _nextOfGCellSubFenceSet(NULL)
|
|
, _nextOfGridFenceSet(NULL)
|
|
, _isARoutingFence(false)
|
|
, _visible(visible)
|
|
, _step (0)
|
|
, _size (size)
|
|
, _grid (grid)
|
|
, _subFences()
|
|
{
|
|
return;
|
|
}
|
|
|
|
Fence::~Fence ()
|
|
{
|
|
return;
|
|
}
|
|
|
|
void Fence::_preDestroy() {
|
|
|
|
//throw Error ("[ERROR] Fence deletion temporarily disabled (to be fixed...)");
|
|
|
|
Inherit::_preDestroy();
|
|
|
|
Fence* parentFence = getParentFence();
|
|
if (parentFence) parentFence->removeSubFence(this);
|
|
|
|
for (
|
|
SplitterSet::iterator spit = _splitters.begin() ;
|
|
spit != _splitters.end() ;
|
|
spit++
|
|
)
|
|
{
|
|
(*spit)->onDeletedFence();
|
|
}
|
|
#if 0
|
|
// remove Fence property ?
|
|
for (
|
|
ComponentSet::iterator cit = _components.begin() ;
|
|
cit != _components.end() ;
|
|
cit++
|
|
)
|
|
{
|
|
(*cit)->onDeletedFence();
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
void Fence::_postCreate ()
|
|
{
|
|
Inherit::_postCreate();
|
|
|
|
//getGCell1()->addSurroundingFence (this);
|
|
//getGCell2()->addSurroundingFence (this);
|
|
Fence* parentFence = getParentFence();
|
|
if (parentFence) parentFence->addSubFence(this);
|
|
|
|
computeCapacity();
|
|
|
|
return;
|
|
};
|
|
|
|
void Fence::setAsRoutingFence()
|
|
{
|
|
if (_isARoutingFence) return;
|
|
_isARoutingFence = true;
|
|
|
|
_grid->getNimbus()->addToRoutingFences(this);
|
|
|
|
return;
|
|
}
|
|
|
|
void Fence::destroy()
|
|
{
|
|
_preDestroy();
|
|
delete this;
|
|
}
|
|
|
|
void Fence::_moveTo (DbU::Unit target)
|
|
{
|
|
for_each_fence (subfence, getSubFences())
|
|
{
|
|
subfence->_moveTo (target);
|
|
end_for;
|
|
}
|
|
return;
|
|
}
|
|
|
|
DbU::Unit Fence::getDistance() const {
|
|
|
|
Point p1 = getGCell1()->getCenter();
|
|
Point p2 = getGCell2()->getCenter();
|
|
|
|
return p1.manhattanDistance(p2);
|
|
}
|
|
|
|
void Fence::attachSplitter (Splitter* splitter)
|
|
{
|
|
_splitters.insert(splitter);
|
|
_occupancy ++;
|
|
|
|
return;
|
|
}
|
|
|
|
void Fence::detachSplitter (Splitter* splitter)
|
|
{
|
|
SplitterSet::iterator spit = _splitters.find (splitter);
|
|
|
|
if (spit != _splitters.end()) {
|
|
_splitters.erase (spit);
|
|
_occupancy --;
|
|
} else {
|
|
throw Error ("DetachSplitter: the splitter is not attached to this fence");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void Fence::attachComponent (Component* component)
|
|
{
|
|
_components.insert(component);
|
|
_occupancy ++;
|
|
|
|
return;
|
|
}
|
|
|
|
void Fence::detachComponent (Component* component)
|
|
{
|
|
ComponentSet::iterator cit = _components.find (component);
|
|
|
|
if (cit != _components.end()) {
|
|
_components.erase (cit);
|
|
_occupancy --;
|
|
} else {
|
|
throw Error ("DetachComponent: the component is not attached to this fence");
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
string Fence::_getString() const {
|
|
return "<" + _TName ( "Fence" )
|
|
+ " " + getString ( getX() )
|
|
+ " " + getString ( getY() ) + ">";
|
|
}
|
|
|
|
Record* Fence::_getRecord() const {
|
|
Record* record = Inherit::_getRecord();
|
|
|
|
if (record) {
|
|
record->add(getSlot("Capacity", _capacity));
|
|
record->add(getSlot("Occupancy", _occupancy));
|
|
record->add(getSlot("Size", _size));
|
|
record->add(getSlot("Step", _step));
|
|
record->add(getSlot("Visible", _visible));
|
|
record->add(getSlot("RoutingFence", _isARoutingFence));
|
|
record->add(getSlot("X", getX()));
|
|
record->add(getSlot("Y", getY()));
|
|
}
|
|
|
|
return record;
|
|
}
|
|
|
|
// void Fence::_Draw(View* view, BasicLayer* basicLayer, const Box& updateArea, const Transformation& transformation)
|
|
// {
|
|
// if (!isVisible()) return;
|
|
// Point p1 = transformation.getPoint(getP1());
|
|
// Point p2 = transformation.getPoint(getP2());
|
|
|
|
// DbU::Unit halfWidth;
|
|
// DbU::Unit pitch = getCDataBase()->getDefaultCGPitch();
|
|
|
|
// if (_capacity != 0)
|
|
// halfWidth = DbU::lambda( (((getValue(_size)/10) * ((double)_occupancy)) / ((double)_capacity))/2 );
|
|
// else
|
|
// halfWidth = DbU::lambda( (((getValue(_size)/10) * ((double)_occupancy)) / 1 )/2 );
|
|
|
|
// if (p1.getX() == p2.getX())
|
|
// {
|
|
// Point pp1 = Point (p1.getX() + halfWidth, p1.getY() + pitch);
|
|
// Point pp2 = Point (p2.getX() - halfWidth, p2.getY() - pitch);
|
|
// view->FillRectangle (pp1, pp2);
|
|
|
|
// Point pp1f = Point (p1.getX() + DbU::lambda(getValue(_size)/20), p1.getY() + pitch);
|
|
// Point pp2f = Point (p2.getX() - DbU::lambda(getValue(_size)/20), p2.getY() - pitch);
|
|
// view->DrawRectangle (pp1f, pp2f);
|
|
// }
|
|
// else if (p1.getY() == p2.getY())
|
|
// {
|
|
// Point pp1 = Point (p1.getX() + pitch, p1.getY() + halfWidth);
|
|
// Point pp2 = Point (p2.getX() - pitch, p2.getY() - halfWidth );
|
|
// view->FillRectangle (pp1, pp2);
|
|
|
|
// Point pp1f = Point (p1.getX() + pitch, p1.getY() + DbU::lambda(getValue(_size)/20));
|
|
// Point pp2f = Point (p2.getX() - pitch, p2.getY() - DbU::lambda(getValue(_size)/20));
|
|
// view->DrawRectangle (pp1f, pp2f);
|
|
// }
|
|
// else
|
|
// {
|
|
// view->DrawLine(p1, p2);
|
|
// }
|
|
|
|
// return;
|
|
// }
|
|
|
|
// void Fence::_Highlight(View* view, const Box& updateArea, const Transformation& transformation)
|
|
// {
|
|
// Point p1 = transformation.getPoint(getP1());
|
|
// Point p2 = transformation.getPoint(getP2());
|
|
|
|
// view->DrawLine(p1, p2);
|
|
|
|
// return;
|
|
// }
|
|
|
|
Box Fence::getBoundingBox () const
|
|
{
|
|
Box box;
|
|
|
|
Point p1 = getP1();
|
|
Point p2 = getP2();
|
|
|
|
if (p1.getX() == p2.getX())
|
|
{
|
|
Point pp1f = Point (p1.getX() + (_size/20), p1.getY() + DbU::lambda(1));
|
|
Point pp2f = Point (p2.getX() - (_size/20), p2.getY() - DbU::lambda(1));
|
|
|
|
box = Box(pp1f);
|
|
box.merge(pp2f);
|
|
}
|
|
else if (p1.getY() == p2.getY())
|
|
{
|
|
Point pp1f = Point (p1.getX() + DbU::lambda(1), p1.getY() + (_size/20));
|
|
Point pp2f = Point (p2.getX() - DbU::lambda(1), p2.getY() - (_size/20));
|
|
|
|
box = Box(pp1f);
|
|
box.merge(pp2f);
|
|
}
|
|
else
|
|
{
|
|
box = Box(p1);
|
|
box.merge(p2);
|
|
}
|
|
box.inflate(DbU::lambda(1), DbU::lambda(2));
|
|
|
|
return box;
|
|
}
|
|
|
|
void Fence::setFrontLine(FrontLine* frontLine)
|
|
{
|
|
if (getFrontLine() != frontLine) throw Error ("Fence is in another frontline already");
|
|
_frontLine = frontLine;
|
|
return;
|
|
}
|
|
|
|
FrontLine* Fence::getFrontLine()
|
|
{
|
|
if (!_frontLine)
|
|
{
|
|
Fence* parentFence = getParentFence();
|
|
if (parentFence) _frontLine = parentFence->getFrontLine();
|
|
}
|
|
return _frontLine;
|
|
}
|
|
|
|
Splitters Fence::getSplitters () const
|
|
{
|
|
return Fence_Splitters(&_splitters);
|
|
}
|
|
|
|
GCells Fence::getGCells () const
|
|
{
|
|
return Fence_GCells(this);
|
|
}
|
|
|
|
void Fence::addSubFence (Fence* fence)
|
|
{
|
|
_subFences._insert(fence);
|
|
return;
|
|
}
|
|
|
|
void Fence::removeSubFence (Fence* fence)
|
|
{
|
|
_subFences._remove(fence);
|
|
return;
|
|
}
|
|
|
|
GCell* Fence::getOppositeGCell (GCell* gcell) const {
|
|
|
|
if (getGCell1() == gcell) {
|
|
return getGCell2();
|
|
} else if (getGCell2() == gcell) {
|
|
return getGCell1();
|
|
}
|
|
|
|
throw Error ("[ERROR] fence: not a gcell of mine");
|
|
}
|
|
|
|
Fence* Fence::getParentFence() const {
|
|
|
|
GCell* gc1 = getGCell1()->getContainer();
|
|
GCell* gc2 = getGCell2()->getContainer();
|
|
|
|
if (gc1 == gc2) return NULL;
|
|
|
|
return _grid->getFenceBetween(gc1,gc2);
|
|
}
|
|
|
|
Splitter* Fence::getNetSplitter(Net* net) const
|
|
{
|
|
for (
|
|
SplitterSet::iterator spit = _splitters.begin() ;
|
|
spit != _splitters.end();
|
|
spit++
|
|
)
|
|
{
|
|
if ( (*spit)->getNet() == net )
|
|
return (*spit);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Cell* Fence::getCell() const {
|
|
return _grid->getCell();
|
|
}
|
|
|
|
// bool Fence::_IsInterceptedBy(View* view, const Point& point, const DbU::Unit& aperture) const
|
|
// {
|
|
// if (!isVisible()) return false;
|
|
|
|
// Box box(point);
|
|
// box.inflate(aperture);
|
|
// return getBoundingBox().intersect(box);
|
|
// }
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence_Splitters implementation
|
|
*
|
|
*/
|
|
|
|
Fence_Splitters::Fence_Splitters(const SplitterSet* spset)
|
|
// **************************************************************************************
|
|
: Inherit()
|
|
, _spset(spset)
|
|
{
|
|
assert(spset);
|
|
_spit = spset->begin();
|
|
}
|
|
|
|
Fence_Splitters::Fence_Splitters(const Fence_Splitters& splitters)
|
|
// ************************************************************************************
|
|
: Inherit()
|
|
, _spset(splitters._spset)
|
|
, _spit(splitters._spit)
|
|
{
|
|
}
|
|
|
|
Fence_Splitters& Fence_Splitters::operator=(const Fence_Splitters& splitters)
|
|
// ****************************************************************
|
|
{
|
|
_spset = splitters._spset;
|
|
_spit = splitters._spit;
|
|
return *this;
|
|
}
|
|
|
|
Collection<Splitter*>* Fence_Splitters::getClone() const
|
|
// ***********************************************
|
|
{
|
|
return new Fence_Splitters(*this);
|
|
}
|
|
|
|
Locator<Splitter*>* Fence_Splitters::getLocator() const
|
|
// **********************************************
|
|
{
|
|
return new Locator(_spset, _spit);
|
|
}
|
|
|
|
string Fence_Splitters::_getString() const
|
|
// *************************************
|
|
{
|
|
string s = "<" + _TName("Fence::Splitters");
|
|
//if (_splitterIterator) s += " " + getString((*_splitterIterator));
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence_Splitters::Locator implementation
|
|
*/
|
|
Fence_Splitters::Locator::Locator(const SplitterSet* spset, SplitterSet::iterator spit)
|
|
// ************************************************************************************
|
|
: Inherit(),
|
|
_spset(spset),
|
|
_spit(spit)
|
|
{
|
|
}
|
|
|
|
Fence_Splitters::Locator::Locator(const Locator& locator)
|
|
// ****************************************************
|
|
: Inherit(),
|
|
_spset(locator._spset),
|
|
_spit(locator._spit)
|
|
{
|
|
}
|
|
|
|
Fence_Splitters::Locator& Fence_Splitters::Locator::operator=(const Locator& locator)
|
|
// ******************************************************************************
|
|
{
|
|
_spset = locator._spset;
|
|
_spit = locator._spit;
|
|
return *this;
|
|
}
|
|
|
|
Splitter* Fence_Splitters::Locator::getElement() const
|
|
// **************************************************
|
|
{
|
|
return (*_spit);
|
|
}
|
|
|
|
Locator<Splitter*>* Fence_Splitters::Locator::getClone() const
|
|
// *****************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Fence_Splitters::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return (_spit != _spset->end());
|
|
}
|
|
|
|
void Fence_Splitters::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
_spit++;
|
|
|
|
return;
|
|
}
|
|
|
|
string Fence_Splitters::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Fence::Splitters::Locator");
|
|
if (_spit != _spset->end()) s += " " + getString(*_spit);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence_GCells implementation
|
|
*/
|
|
Fence_GCells::Fence_GCells(const Fence* fence)
|
|
// **************************************************************************************
|
|
: Inherit()
|
|
, _fence(fence)
|
|
, _gc(fence->getGCell1())
|
|
{
|
|
}
|
|
|
|
Fence_GCells::Fence_GCells(const Fence_GCells& gcelles)
|
|
// ************************************************************************************
|
|
: Inherit()
|
|
, _fence(gcelles._fence)
|
|
, _gc(gcelles._gc)
|
|
{
|
|
}
|
|
|
|
Fence_GCells& Fence_GCells::operator=(const Fence_GCells& gcelles)
|
|
// ****************************************************************
|
|
{
|
|
_fence = gcelles._fence;
|
|
_gc = gcelles._gc;
|
|
return *this;
|
|
}
|
|
|
|
Collection<GCell*>* Fence_GCells::getClone() const
|
|
// ***********************************************
|
|
{
|
|
return new Fence_GCells(*this);
|
|
}
|
|
|
|
Locator<GCell*>* Fence_GCells::getLocator() const
|
|
// **********************************************
|
|
{
|
|
return new Locator(_fence, _gc);
|
|
}
|
|
|
|
string Fence_GCells::_getString() const
|
|
// *************************************
|
|
{
|
|
string s = "<" + _TName("Fence::GCells");
|
|
if (_gc) s += " " + getString(_gc);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* Fence_GCells::Locator implementation
|
|
*/
|
|
Fence_GCells::Locator::Locator(const Fence* fence, GCell* gcell)
|
|
// ********************************************************
|
|
: Inherit(),
|
|
_fence(fence),
|
|
_gc(gcell)
|
|
{
|
|
}
|
|
|
|
Fence_GCells::Locator::Locator(const Locator& locator)
|
|
// ****************************************************
|
|
: Inherit(),
|
|
_fence(locator._fence),
|
|
_gc(locator._gc)
|
|
{
|
|
}
|
|
|
|
Fence_GCells::Locator& Fence_GCells::Locator::operator=(const Locator& locator)
|
|
// ******************************************************************************
|
|
{
|
|
_fence = locator._fence;
|
|
_gc = locator._gc;
|
|
return *this;
|
|
}
|
|
|
|
GCell* Fence_GCells::Locator::getElement() const
|
|
// **************************************************
|
|
{
|
|
return _gc;
|
|
}
|
|
|
|
Locator<GCell*>* Fence_GCells::Locator::getClone() const
|
|
// *****************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Fence_GCells::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return (_gc != NULL);
|
|
}
|
|
|
|
void Fence_GCells::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
if (_gc == _fence->getGCell1()) {
|
|
_gc = _fence->getGCell2();
|
|
} else {
|
|
_gc = NULL;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
string Fence_GCells::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Fence::GCells::Locator");
|
|
if (_gc) s += " " + getString(_gc);
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
/*
|
|
* ********************************************************************
|
|
* SubFenceSet implementation
|
|
*
|
|
*/
|
|
Fence::SubFenceSet::SubFenceSet()
|
|
// *******************************
|
|
: Inherit()
|
|
{
|
|
}
|
|
|
|
unsigned Fence::SubFenceSet::_getHashValue(Fence* fence) const
|
|
{
|
|
return ( (unsigned int)( (unsigned long)fence ) ) / 2;
|
|
}
|
|
|
|
Fence* Fence::SubFenceSet::_getNextElement(Fence* fence) const
|
|
{
|
|
return fence->_getNextOfFenceSubFenceSet();
|
|
}
|
|
|
|
void Fence::SubFenceSet::_setNextElement(Fence* fence, Fence* nextFence) const
|
|
{
|
|
fence->_setNextOfFenceSubFenceSet(nextFence);
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
} // namespace Nimbus
|