582 lines
17 KiB
C++
582 lines
17 KiB
C++
// ****************************************************************************************************
|
|
// File: ./Technology.cpp
|
|
// Authors: R. Escassut
|
|
// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved
|
|
//
|
|
// This file is part of Hurricane.
|
|
//
|
|
// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU
|
|
// Lesser General Public License as published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// Hurricane is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If
|
|
// not, see <http://www.gnu.org/licenses/>.
|
|
// ****************************************************************************************************
|
|
|
|
#include "hurricane/Technology.h"
|
|
#include "hurricane/DataBase.h"
|
|
#include "hurricane/Layer.h"
|
|
#include "hurricane/BasicLayer.h"
|
|
#include "hurricane/RegularLayer.h"
|
|
#include "hurricane/ViaLayer.h"
|
|
#include "hurricane/Error.h"
|
|
|
|
|
|
|
|
namespace Hurricane {
|
|
|
|
|
|
|
|
// ****************************************************************************************************
|
|
// Technology_BasicLayers declaration
|
|
// ****************************************************************************************************
|
|
|
|
class Technology_BasicLayers : public Collection<BasicLayer*> {
|
|
// **********************************************************
|
|
|
|
// Types
|
|
// *****
|
|
|
|
public: typedef Collection<BasicLayer*> Inherit;
|
|
|
|
public: class Locator : public Hurricane::Locator<BasicLayer*> {
|
|
// ***********************************************************
|
|
|
|
public: typedef Hurricane::Locator<BasicLayer*> Inherit;
|
|
|
|
private: const Technology* _technology;
|
|
private: Layer::Mask _mask;
|
|
private: BasicLayerLocator _basicLayerLocator;
|
|
|
|
public: Locator();
|
|
public: Locator(const Technology* technology, const Layer::Mask& mask);
|
|
public: Locator(const Locator& locator);
|
|
|
|
public: Locator& operator=(const Locator& locator);
|
|
|
|
public: virtual BasicLayer* getElement() const;
|
|
public: virtual Hurricane::Locator<BasicLayer*>* getClone() const;
|
|
|
|
public: virtual bool isValid() const;
|
|
|
|
public: virtual void progress();
|
|
|
|
public: virtual string _getString() const;
|
|
|
|
};
|
|
|
|
// Attributes
|
|
// **********
|
|
|
|
private: const Technology* _technology;
|
|
private: Layer::Mask _mask;
|
|
|
|
// Constructors
|
|
// ************
|
|
|
|
public: Technology_BasicLayers();
|
|
public: Technology_BasicLayers(const Technology* technology, const Layer::Mask& mask);
|
|
public: Technology_BasicLayers(const Technology_BasicLayers& basicLayers);
|
|
|
|
// Operators
|
|
// *********
|
|
|
|
public: Technology_BasicLayers& operator=(const Technology_BasicLayers& basicLayers);
|
|
|
|
// Accessors
|
|
// *********
|
|
|
|
public: virtual Collection<BasicLayer*>* getClone() const;
|
|
public: virtual Hurricane::Locator<BasicLayer*>* getLocator() const;
|
|
|
|
// Others
|
|
// ******
|
|
|
|
public: virtual string _getString() const;
|
|
|
|
};
|
|
|
|
// ****************************************************************************************************
|
|
// Technology implementation
|
|
// ****************************************************************************************************
|
|
|
|
Technology::Technology(DataBase* dataBase, const Name& name)
|
|
// *********************************************************
|
|
: Inherit(),
|
|
_dataBase(dataBase),
|
|
_name(name),
|
|
_layerMap(),
|
|
_layerMaskMap()
|
|
{
|
|
if (!_dataBase)
|
|
throw Error("Can't create " + _TName("Technology") + " : null data base");
|
|
|
|
if (_dataBase->getTechnology())
|
|
throw Error("Can't create " + _TName("Technology") + " : already exists");
|
|
|
|
if (_name.isEmpty())
|
|
throw Error("Can't create " + _TName("Technology") + " : empty name");
|
|
}
|
|
|
|
Technology* Technology::create(DataBase* dataBase, const Name& name)
|
|
// *****************************************************************
|
|
{
|
|
Technology* technology = new Technology(dataBase, name);
|
|
|
|
technology->_postCreate();
|
|
|
|
return technology;
|
|
}
|
|
|
|
// Layer* Technology::getLayer ( Layer::Mask mask ) const
|
|
// // ***************************************************
|
|
// {
|
|
// LayerMaskMap::const_iterator ilayer = _layerMaskMap.find(mask);
|
|
// if ( ilayer == _layerMaskMap.end() )
|
|
// return NULL;
|
|
|
|
// return ilayer->second;
|
|
// }
|
|
|
|
BasicLayer* Technology::getBasicLayer(const Name& name) const
|
|
// **********************************************************
|
|
{
|
|
Layer* layer = getLayer(name);
|
|
return (layer && dynamic_cast<BasicLayer*>(layer)) ? (BasicLayer*)layer : NULL;
|
|
}
|
|
|
|
RegularLayer* Technology::getRegularLayer(const Name& name) const
|
|
// **********************************************************
|
|
{
|
|
Layer* layer = getLayer(name);
|
|
return (layer && dynamic_cast<RegularLayer*>(layer)) ? (RegularLayer*)layer : NULL;
|
|
}
|
|
|
|
ViaLayer* Technology::getViaLayer(const Name& name) const
|
|
// ******************************************************************
|
|
{
|
|
Layer* layer = getLayer(name);
|
|
return (layer && dynamic_cast<ViaLayer*>(layer)) ? (ViaLayer*)layer : NULL;
|
|
}
|
|
|
|
BasicLayers Technology::getBasicLayers() const
|
|
// *******************************************
|
|
{
|
|
// return getLayers().getSubSet<BasicLayer*>();
|
|
return SubTypeCollection<Layer*, BasicLayer*>(getLayers());
|
|
}
|
|
|
|
BasicLayers Technology::getBasicLayers(const Layer::Mask& mask) const
|
|
// ******************************************************************
|
|
{
|
|
return Technology_BasicLayers(this, mask);
|
|
}
|
|
|
|
RegularLayers Technology::getRegularLayers() const
|
|
// ***************************************************
|
|
{
|
|
return SubTypeCollection<Layer*, RegularLayer*>(getLayers());
|
|
}
|
|
|
|
ViaLayers Technology::getViaLayers() const
|
|
// ***************************************************
|
|
{
|
|
return SubTypeCollection<Layer*, ViaLayer*>(getLayers());
|
|
}
|
|
|
|
|
|
Layer* Technology::getLayer ( const Layer::Mask& mask, bool useWorking ) const
|
|
{
|
|
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound ( mask );
|
|
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( mask );
|
|
for ( ; lb != ub ; lb++ ) {
|
|
if ( !useWorking || lb->second->isWorking() ) return lb->second;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Layer* Technology::getMetalAbove ( const Layer* layer, bool useWorking ) const
|
|
{
|
|
if ( !layer ) return NULL;
|
|
|
|
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
|
for ( ; ub != _layerMaskMap.end() ; ub++ ) {
|
|
if ( _metalMask.contains(ub->second->getMask())
|
|
&& ( !useWorking || ub->second->isWorking() ) )
|
|
return ub->second;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Layer* Technology::getMetalBelow ( const Layer* layer, bool useWorking ) const
|
|
{
|
|
if ( !layer ) return NULL;
|
|
|
|
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
|
if ( lb->second == layer ) lb--;
|
|
for ( ; lb != _layerMaskMap.begin() ; lb-- ) {
|
|
if ( _metalMask.contains(lb->second->getMask())
|
|
&& ( !useWorking || lb->second->isWorking() ) )
|
|
return lb->second;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Layer* Technology::getCutAbove ( const Layer* layer, bool useWorking ) const
|
|
{
|
|
if ( !layer ) return NULL;
|
|
|
|
LayerMaskMap::const_iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
|
for ( ; ub != _layerMaskMap.end() ; ub++ ) {
|
|
if ( _cutMask.contains(ub->second->getMask())
|
|
&& ( !useWorking || ub->second->isWorking() ) )
|
|
return ub->second;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Layer* Technology::getCutBelow ( const Layer* layer, bool useWorking ) const
|
|
{
|
|
if ( !layer ) return NULL;
|
|
|
|
LayerMaskMap::const_iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
|
if ( lb->second == layer ) lb--;
|
|
for ( ; lb != _layerMaskMap.begin() ; lb-- ) {
|
|
if ( _cutMask.contains(lb->second->getMask())
|
|
&& ( !useWorking || lb->second->isWorking() ) )
|
|
return lb->second;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
Layer* Technology::getViaBetween ( const Layer* metal1, const Layer* metal2 ) const
|
|
{
|
|
if ( !metal1 || !metal2 ) return NULL;
|
|
if ( metal1->above(metal2) ) swap ( metal1, metal2 );
|
|
|
|
Layer* cutLayer = getCutBelow ( metal2 );
|
|
if ( !cutLayer ) return NULL;
|
|
|
|
return getLayer ( metal1->getMask() | metal2->getMask() | cutLayer->getMask() );
|
|
}
|
|
|
|
|
|
Layer* Technology::getNthMetal ( int nth ) const
|
|
{
|
|
return getLayer ( _metalMask.nthbit(nth) );
|
|
}
|
|
|
|
|
|
void Technology::_onDbuChange ( float scale )
|
|
{
|
|
forEach ( Layer*, layer, getLayers() )
|
|
layer->_onDbuChange ( scale );
|
|
}
|
|
|
|
|
|
void Technology::setName(const Name& name)
|
|
// ***************************************
|
|
{
|
|
if (name != _name) {
|
|
if (name.isEmpty())
|
|
throw Error("Can't change technology name : empty name");
|
|
|
|
_name = name;
|
|
}
|
|
}
|
|
|
|
|
|
bool Technology::setWorkingLayer ( const Name& name )
|
|
{
|
|
Layer* layer = getLayer ( name );
|
|
if ( !layer ) return false;
|
|
|
|
return setWorkingLayer ( layer );
|
|
}
|
|
|
|
|
|
bool Technology::setWorkingLayer ( const Layer* layer )
|
|
{
|
|
bool found = false;
|
|
LayerMaskMap::iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
|
LayerMaskMap::iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
|
for ( ; lb != ub ; lb++ ) {
|
|
if ( lb->second == layer ) {
|
|
lb->second->setWorking ( true );
|
|
found = true;
|
|
} else
|
|
lb->second->setWorking ( false );
|
|
}
|
|
return found;
|
|
}
|
|
|
|
|
|
void Technology::_postCreate()
|
|
// ***************************
|
|
{
|
|
Inherit::_postCreate();
|
|
|
|
_dataBase->_setTechnology(this);
|
|
}
|
|
|
|
void Technology::_preDestroy()
|
|
// **************************
|
|
{
|
|
|
|
while ( !_layerMap.isEmpty() ) {
|
|
_layerMap.getElements().getFirst()->destroy();
|
|
}
|
|
//for_each_layer(layer, getLayers()) layer->destroy(); end_for;
|
|
|
|
_dataBase->_setTechnology(NULL);
|
|
DBo::_preDestroy();
|
|
}
|
|
|
|
void Technology::_insertInLayerMaskMap ( Layer* layer )
|
|
// ****************************************************
|
|
{
|
|
_layerMaskMap.insert ( make_pair(layer->getMask(),layer) );
|
|
}
|
|
|
|
void Technology::_removeFromLayerMaskMap ( Layer* layer )
|
|
// ******************************************************
|
|
{
|
|
LayerMaskMap::iterator lb = _layerMaskMap.lower_bound ( layer->getMask() );
|
|
LayerMaskMap::iterator ub = _layerMaskMap.upper_bound ( layer->getMask() );
|
|
|
|
for ( ; lb != ub ; lb++ ) {
|
|
if ( lb->second == layer ) {
|
|
_layerMaskMap.erase ( lb );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
string Technology::_getTypeName () const
|
|
{
|
|
return _TName("Technology");
|
|
}
|
|
|
|
|
|
|
|
string Technology::_getString() const
|
|
// **********************************
|
|
{
|
|
string s = Inherit::_getString();
|
|
s.insert(s.length() - 1, " " + getString(_name));
|
|
return s;
|
|
}
|
|
|
|
Record* Technology::_getRecord() const
|
|
// *****************************
|
|
{
|
|
Record* record = Inherit::_getRecord();
|
|
if (record) {
|
|
record->add(getSlot("DataBase", _dataBase));
|
|
record->add(getSlot("Name", &_name));
|
|
record->add(getSlot("Layers", &_layerMaskMap));
|
|
record->add(getSlot("cutMask", &_cutMask));
|
|
record->add(getSlot("metalMask", &_metalMask));
|
|
}
|
|
return record;
|
|
}
|
|
|
|
// ****************************************************************************************************
|
|
// Technology::LayerMap implementation
|
|
// ****************************************************************************************************
|
|
|
|
Technology::LayerMap::LayerMap()
|
|
// *****************************
|
|
: Inherit()
|
|
{
|
|
}
|
|
|
|
Name Technology::LayerMap::_getKey(Layer* layer) const
|
|
// ***************************************************
|
|
{
|
|
return layer->getName();
|
|
}
|
|
|
|
unsigned Technology::LayerMap::_getHashValue(Name name) const
|
|
// **********************************************************
|
|
{
|
|
return ( (unsigned int)( (unsigned long)name._getSharedName() ) ) / 8;
|
|
}
|
|
|
|
Layer* Technology::LayerMap::_getNextElement(Layer* layer) const
|
|
// *************************************************************
|
|
{
|
|
return layer->_getNextOfTechnologyLayerMap();
|
|
}
|
|
|
|
void Technology::LayerMap::_setNextElement(Layer* layer, Layer* nextLayer) const
|
|
// *****************************************************************************
|
|
{
|
|
layer->_setNextOfTechnologyLayerMap(nextLayer);
|
|
};
|
|
|
|
|
|
|
|
// ****************************************************************************************************
|
|
// Technology_BasicLayers implementation
|
|
// ****************************************************************************************************
|
|
|
|
Technology_BasicLayers::Technology_BasicLayers()
|
|
// *********************************************
|
|
: Inherit(),
|
|
_technology(NULL),
|
|
_mask(0)
|
|
{
|
|
}
|
|
|
|
Technology_BasicLayers::Technology_BasicLayers(const Technology* technology, const Layer::Mask& mask)
|
|
// **************************************************************************************************
|
|
: Inherit(),
|
|
_technology(technology),
|
|
_mask(mask)
|
|
{
|
|
}
|
|
|
|
Technology_BasicLayers::Technology_BasicLayers(const Technology_BasicLayers& basicLayers)
|
|
// **************************************************************************************
|
|
: Inherit(),
|
|
_technology(basicLayers._technology),
|
|
_mask(basicLayers._mask)
|
|
{
|
|
}
|
|
|
|
Technology_BasicLayers& Technology_BasicLayers::operator=(const Technology_BasicLayers& basicLayers)
|
|
// *************************************************************************************************
|
|
{
|
|
_technology = basicLayers._technology;
|
|
_mask = basicLayers._mask;
|
|
return *this;
|
|
}
|
|
|
|
Collection<BasicLayer*>* Technology_BasicLayers::getClone() const
|
|
// **************************************************************
|
|
{
|
|
return new Technology_BasicLayers(*this);
|
|
}
|
|
|
|
Locator<BasicLayer*>* Technology_BasicLayers::getLocator() const
|
|
// *************************************************************
|
|
{
|
|
return new Locator(_technology, _mask);
|
|
}
|
|
|
|
string Technology_BasicLayers::_getString() const
|
|
// **********************************************
|
|
{
|
|
string s = "<" + _TName("Technology::BasicLayers");
|
|
if (_technology) {
|
|
s += " " + getString(_technology);
|
|
s += " " + getString(_mask);
|
|
}
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
// ****************************************************************************************************
|
|
// Technology_BasicLayers::Locator implementation
|
|
// ****************************************************************************************************
|
|
|
|
Technology_BasicLayers::Locator::Locator()
|
|
// ***************************************
|
|
: Inherit(),
|
|
_technology(NULL),
|
|
_mask(0),
|
|
_basicLayerLocator()
|
|
{
|
|
}
|
|
|
|
Technology_BasicLayers::Locator::Locator(const Technology* technology, const Layer::Mask& mask)
|
|
// ********************************************************************************************
|
|
: Inherit(),
|
|
_technology(technology),
|
|
_mask(mask),
|
|
_basicLayerLocator()
|
|
{
|
|
if (_technology) {
|
|
_basicLayerLocator = _technology->getBasicLayers().getLocator();
|
|
while (_basicLayerLocator.isValid() && !(_basicLayerLocator.getElement()->getMask() & _mask))
|
|
_basicLayerLocator.progress();
|
|
}
|
|
}
|
|
|
|
Technology_BasicLayers::Locator::Locator(const Locator& locator)
|
|
// *************************************************************
|
|
: Inherit(),
|
|
_technology(locator._technology),
|
|
_mask(locator._mask),
|
|
_basicLayerLocator(locator._basicLayerLocator)
|
|
{
|
|
}
|
|
|
|
Technology_BasicLayers::Locator& Technology_BasicLayers::Locator::operator=(const Locator& locator)
|
|
// ************************************************************************************************
|
|
{
|
|
_technology = locator._technology;
|
|
_mask = locator._mask;
|
|
_basicLayerLocator = locator._basicLayerLocator;
|
|
return *this;
|
|
}
|
|
|
|
BasicLayer* Technology_BasicLayers::Locator::getElement() const
|
|
// ************************************************************
|
|
{
|
|
return _basicLayerLocator.getElement();
|
|
}
|
|
|
|
Locator<BasicLayer*>* Technology_BasicLayers::Locator::getClone() const
|
|
// ********************************************************************
|
|
{
|
|
return new Locator(*this);
|
|
}
|
|
|
|
bool Technology_BasicLayers::Locator::isValid() const
|
|
// **************************************************
|
|
{
|
|
return _basicLayerLocator.isValid();
|
|
}
|
|
|
|
void Technology_BasicLayers::Locator::progress()
|
|
// *********************************************
|
|
{
|
|
do {
|
|
_basicLayerLocator.progress();
|
|
}
|
|
while (_basicLayerLocator.isValid() && !(_basicLayerLocator.getElement()->getMask() & _mask));
|
|
}
|
|
|
|
string Technology_BasicLayers::Locator::_getString() const
|
|
// *******************************************************
|
|
{
|
|
string s = "<" + _TName("Technology::BasicLayers::Locator");
|
|
if (_technology) {
|
|
s += " " + getString(_technology);
|
|
s += " " + getString(_mask);
|
|
}
|
|
s += ">";
|
|
return s;
|
|
}
|
|
|
|
} // End of Hurricane namespace.
|
|
|
|
|
|
// ****************************************************************************************************
|
|
// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved
|
|
// ****************************************************************************************************
|