2018-10-18 11:10:01 -05:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
|
|
|
// Copyright (c) UPMC 2015-2018, All Rights Reserved
|
|
|
|
//
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
// | C O R I O L I S |
|
|
|
|
// | B o r a - A n a l o g S l i c i n g T r e e |
|
|
|
|
// | |
|
|
|
|
// | Authors : Eric LAO |
|
|
|
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./DSlicingNode.cpp" |
|
|
|
|
// +-----------------------------------------------------------------+
|
|
|
|
|
|
|
|
|
|
|
|
#include "hurricane/Error.h"
|
|
|
|
#include "hurricane/Warning.h"
|
|
|
|
#include "hurricane/analog/Device.h"
|
|
|
|
#include "hurricane/analog/FormFactorParameter.h"
|
|
|
|
#include "hurricane/analog/TransistorFamily.h"
|
|
|
|
#include "hurricane/analog/Transistor.h"
|
|
|
|
#include "hurricane/analog/CommonSourcePair.h"
|
|
|
|
#include "hurricane/analog/DifferentialPair.h"
|
|
|
|
#include "hurricane/analog/LayoutGenerator.h"
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
#include "hurricane/analog/MultiCapacitor.h"
|
2018-10-18 11:10:01 -05:00
|
|
|
#include "anabatic/Session.h"
|
|
|
|
#include "bora/DSlicingNode.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Bora {
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using Hurricane::Error;
|
|
|
|
using Hurricane::Warning;
|
|
|
|
using Hurricane::Transformation;
|
|
|
|
using Analog::Device;
|
|
|
|
using Analog::FormFactorParameter;
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
using Analog::MatrixParameter;
|
2018-10-18 11:10:01 -05:00
|
|
|
using Analog::TransistorFamily;
|
|
|
|
using Analog::Transistor;
|
|
|
|
using Analog::CommonSourcePair;
|
|
|
|
using Analog::DifferentialPair;
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
using Analog::MultiCapacitor;
|
2018-10-18 11:10:01 -05:00
|
|
|
using Analog::LayoutGenerator;
|
|
|
|
using Anabatic::Session;
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Bora::DSlicingNode".
|
|
|
|
|
|
|
|
|
|
|
|
int DSlicingNode::_count = 0;
|
|
|
|
int DSlicingNode::_countAll = 0;
|
|
|
|
|
|
|
|
|
|
|
|
DSlicingNode::DSlicingNode ( unsigned int type
|
|
|
|
, NodeSets* nodeSets
|
|
|
|
, unsigned int alignment
|
|
|
|
, Instance* instance
|
|
|
|
, BoxSet* boxSet
|
|
|
|
)
|
|
|
|
: SlicingNode( type, nodeSets, alignment, boxSet )
|
|
|
|
, _instance(instance)
|
|
|
|
{ ++_count; }
|
|
|
|
|
|
|
|
|
|
|
|
DSlicingNode::~DSlicingNode ()
|
|
|
|
{ --_count; }
|
|
|
|
|
|
|
|
|
|
|
|
DSlicingNode* DSlicingNode::create ( NodeSets* nodeSets
|
|
|
|
, unsigned int alignment
|
|
|
|
, Instance* instance
|
|
|
|
, BoxSet* boxSet
|
|
|
|
)
|
|
|
|
{
|
|
|
|
_countAll++;
|
|
|
|
|
|
|
|
return new DSlicingNode( DeviceSNode, nodeSets, alignment, instance, boxSet );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::print () const
|
|
|
|
{
|
|
|
|
cerr << "- Print from Slicing Node - " << endl;
|
|
|
|
cerr << "SlicingType: Device Node" << endl;
|
|
|
|
if (isAlignLeft ()) cerr << "Alignment : Left" << endl;
|
|
|
|
else if (isAlignCenter()) cerr << "Alignment : Middle" << endl;
|
|
|
|
else if (isAlignRight ()) cerr << "Alignment : Right" << endl;
|
|
|
|
else if (isAlignTop ()) cerr << "Alignment : Top" << endl;
|
|
|
|
else if (isAlignBottom()) cerr << "Alignment : Bottom" << endl;
|
|
|
|
else cerr << "Alignment : Unknown" << endl;
|
Added Resistor support. Completed Capacitor & Resistor support in Bora.
* New: In Analog, added Analog::ResitorFamily & Analog::Resistor classes.
* New: In Analog, added inspector support for all Parameter classes.
* New: In Analog, new FloatParameter class (for resistor value).
* New: In CRL/etc/scn6m_deep_09/devices.py, added resistor device.
* New: In Oroshi, support for Resistors, stub for ResistorSnake generator.
* New: In Bora::DNodeSets, added support for Resistor devices.
* Change: In Bora::DSlicingNode, rename setNFing()/getNFing() into
setBoxSetIndex()/getBoxSetIndex() for semantic coherency.
* New: In Karakaze/python/AnalogDesign.py, added support for Resistor.
Change in addDevice(), the span which was only meaningful for
transistor devices is replaced by a parameter argument.
The parameter argument has to be consistent with the device type.
2019-11-11 19:21:03 -06:00
|
|
|
cerr << "BoxSetIndex : " << getBoxSetIndex() << endl;
|
2018-10-18 11:10:01 -05:00
|
|
|
if (_instance) cerr << "Instance : " << _instance << endl;
|
|
|
|
else cerr << "Instance : None" << endl;
|
|
|
|
SlicingNode::print();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DSlicingNode* DSlicingNode::clone ( unsigned int tr )
|
|
|
|
{
|
|
|
|
DSlicingNode* node = DSlicingNode::create( _nodeSets->clone()
|
|
|
|
, getAlignment()
|
|
|
|
, getInstance()
|
|
|
|
, getBoxSet()
|
|
|
|
);
|
|
|
|
node->setPreset( getPreset() );
|
|
|
|
node->setSet ( getSet() );
|
|
|
|
node->setPlaced( getPlaced() );
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Added Resistor support. Completed Capacitor & Resistor support in Bora.
* New: In Analog, added Analog::ResitorFamily & Analog::Resistor classes.
* New: In Analog, added inspector support for all Parameter classes.
* New: In Analog, new FloatParameter class (for resistor value).
* New: In CRL/etc/scn6m_deep_09/devices.py, added resistor device.
* New: In Oroshi, support for Resistors, stub for ResistorSnake generator.
* New: In Bora::DNodeSets, added support for Resistor devices.
* Change: In Bora::DSlicingNode, rename setNFing()/getNFing() into
setBoxSetIndex()/getBoxSetIndex() for semantic coherency.
* New: In Karakaze/python/AnalogDesign.py, added support for Resistor.
Change in addDevice(), the span which was only meaningful for
transistor devices is replaced by a parameter argument.
The parameter argument has to be consistent with the device type.
2019-11-11 19:21:03 -06:00
|
|
|
void DSlicingNode::setBoxSetIndex ( size_t index )
|
|
|
|
{ _boxSet = _nodeSets->find( index ); }
|
2018-10-18 11:10:01 -05:00
|
|
|
|
|
|
|
|
Added Resistor support. Completed Capacitor & Resistor support in Bora.
* New: In Analog, added Analog::ResitorFamily & Analog::Resistor classes.
* New: In Analog, added inspector support for all Parameter classes.
* New: In Analog, new FloatParameter class (for resistor value).
* New: In CRL/etc/scn6m_deep_09/devices.py, added resistor device.
* New: In Oroshi, support for Resistors, stub for ResistorSnake generator.
* New: In Bora::DNodeSets, added support for Resistor devices.
* Change: In Bora::DSlicingNode, rename setNFing()/getNFing() into
setBoxSetIndex()/getBoxSetIndex() for semantic coherency.
* New: In Karakaze/python/AnalogDesign.py, added support for Resistor.
Change in addDevice(), the span which was only meaningful for
transistor devices is replaced by a parameter argument.
The parameter argument has to be consistent with the device type.
2019-11-11 19:21:03 -06:00
|
|
|
size_t DSlicingNode::getBoxSetIndex () const
|
|
|
|
{ return (_boxSet) ? _boxSet->getIndex() : 0 ; }
|
2018-10-18 11:10:01 -05:00
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::_place( DbU::Unit x, DbU::Unit y, bool replace )
|
|
|
|
{
|
|
|
|
cdebug_log(536,1) << "DSlicingNode::_place(DbU::Unit,DbU::Unit,bool replace)" << endl;
|
|
|
|
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
if (replace) {
|
2018-10-18 11:10:01 -05:00
|
|
|
SlicingNode::place( x, y );
|
|
|
|
if (_instance) {
|
|
|
|
Cell* model = _instance->getMasterCell();
|
|
|
|
_instance->setTransformation ( Transformation( _x - model->getAbutmentBox().getXMin()
|
|
|
|
, _y - model->getAbutmentBox().getYMin() ) );
|
|
|
|
_instance->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (isSet()) {
|
|
|
|
SlicingNode::place( x, y );
|
|
|
|
|
|
|
|
if (_instance) {
|
|
|
|
Cell* model = _instance->getMasterCell();
|
|
|
|
Device* device = dynamic_cast<Device*>( model );
|
|
|
|
|
|
|
|
if (device) {
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
unique_ptr<LayoutGenerator> layoutGenerator ( new LayoutGenerator() );
|
|
|
|
|
2018-10-18 11:10:01 -05:00
|
|
|
TransistorFamily* tf = dynamic_cast<TransistorFamily*>( device );
|
|
|
|
if (tf) {
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
StepParameterRange* stepRange = dynamic_cast<StepParameterRange*>( getNodeSets()->getRange() );
|
|
|
|
if (not stepRange) {
|
|
|
|
throw Error( "DSlicingNode::_place(): Device \"%s\" must be associated with a StepParameterRange argument instead of %s."
|
|
|
|
, getString(device->getName()).c_str()
|
|
|
|
, getString(stepRange).c_str()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
stepRange->setIndex( getBoxSet()->getIndex() );
|
|
|
|
int nfingers = stepRange->getValue();
|
|
|
|
|
|
|
|
tf->setNfing( nfingers );
|
|
|
|
layoutGenerator->setDevice ( device );
|
2018-10-18 11:10:01 -05:00
|
|
|
layoutGenerator->drawLayout();
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
} else {
|
|
|
|
MultiCapacitor* mcapacitor = dynamic_cast<MultiCapacitor *>( device );
|
|
|
|
MatrixParameterRange* matrixRange = dynamic_cast<MatrixParameterRange*>( getNodeSets()->getRange() );
|
|
|
|
|
|
|
|
if (mcapacitor) {
|
|
|
|
if (not matrixRange) {
|
|
|
|
throw Error( "DSlicingNode::create(): Device \"%s\" must be associated with a MatrixParameterRange argument instead of %s."
|
|
|
|
, getString(mcapacitor->getName()).c_str()
|
|
|
|
, getString(matrixRange).c_str()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
matrixRange->setIndex( getBoxSet()->getIndex() );
|
|
|
|
MatrixParameter* mp = NULL;
|
|
|
|
if ( (mp = dynamic_cast<MatrixParameter*>(mcapacitor->getParameter("Matrix"))) != NULL )
|
|
|
|
mp->setMatrix( &matrixRange->getValue() );
|
|
|
|
|
|
|
|
layoutGenerator->setDevice( mcapacitor );
|
|
|
|
layoutGenerator->drawLayout();
|
|
|
|
}
|
2018-10-18 11:10:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_instance->setTransformation ( Transformation( _x - model->getAbutmentBox().getXMin()
|
|
|
|
, _y - model->getAbutmentBox().getYMin() ) );
|
|
|
|
_instance->setPlacementStatus( Instance::PlacementStatus::PLACED );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_tabw(536,-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::place ( DbU::Unit x, DbU::Unit y )
|
|
|
|
{ DSlicingNode::_place(x, y); }
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::preDestroy ()
|
|
|
|
{
|
|
|
|
SlicingNode::preDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::destroy()
|
|
|
|
{
|
|
|
|
DSlicingNode::preDestroy();
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::preRecursiveDestroy ()
|
|
|
|
{
|
|
|
|
SlicingNode::preRecursiveDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::recursiveDestroy ()
|
|
|
|
{
|
|
|
|
DSlicingNode::preRecursiveDestroy();
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DSlicingNode::checkInitialPlacement ( int& cpt ) const
|
|
|
|
{
|
|
|
|
// Notes: Initial placement criteria is having at least 2 devices
|
|
|
|
// placed at (x,y) = (0 0)
|
|
|
|
//
|
|
|
|
// jpc: Very suspicious code, have to check how it is called.
|
|
|
|
|
|
|
|
bool initialPlacement = false;
|
|
|
|
if (cpt < 2) {
|
|
|
|
if ( (_x == 0) and (_y == 0) ) {
|
|
|
|
cpt++;
|
|
|
|
if (cpt < 2) initialPlacement = true;
|
|
|
|
} else
|
|
|
|
initialPlacement = true;
|
|
|
|
}
|
|
|
|
return initialPlacement;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::setGCell ( Anabatic::GCell* gcell )
|
|
|
|
{
|
|
|
|
cdebug_log(535,0) << "DSlicingNode::setGCell(Anabatic::GCell*) " << gcell << endl;
|
|
|
|
|
|
|
|
if (getParent()) {
|
|
|
|
if (getParent()->getType() == HorizontalSNode) {
|
|
|
|
if (getAlignment() == AlignLeft) {
|
|
|
|
Anabatic::GCell* strut = gcell->vcut( getX() + getWidth() );
|
|
|
|
_gcell = gcell;
|
|
|
|
strut->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
} else if (getAlignment() == AlignCenter) {
|
|
|
|
_gcell = gcell->vcut( getX() );
|
|
|
|
Anabatic::GCell* strut = _gcell->vcut( getX() + getWidth() );
|
|
|
|
gcell->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
strut->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
} else if (getAlignment() == AlignRight ){
|
|
|
|
_gcell = gcell->vcut( getX() );
|
|
|
|
gcell->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
}
|
|
|
|
} else if (getParent()->getType() == VerticalSNode) {
|
|
|
|
if (getAlignment() == AlignBottom){
|
|
|
|
Anabatic::GCell* strut = gcell->hcut( getY() + getHeight() );
|
|
|
|
_gcell = gcell;
|
|
|
|
strut->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
} else if (getAlignment() == AlignCenter) {
|
|
|
|
_gcell = gcell->hcut( getY() );
|
|
|
|
Anabatic::GCell* strut = _gcell->hcut( getY() + getHeight() );
|
|
|
|
gcell->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
strut->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
} else if (getAlignment() == AlignTop) {
|
|
|
|
_gcell = gcell->hcut( getY() );
|
|
|
|
gcell->setType( Anabatic::Flags::StrutGCell );
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
_gcell = gcell;
|
|
|
|
} else
|
|
|
|
_gcell = gcell;
|
|
|
|
|
|
|
|
if (_gcell) {
|
|
|
|
if (dynamic_cast<Device*>(_instance->getMasterCell())) {
|
|
|
|
_gcell->setType( Anabatic::Flags::DeviceGCell );
|
|
|
|
} else {
|
|
|
|
_gcell->setType( Anabatic::Flags::MatrixGCell );
|
|
|
|
if( (_gcell->getWidth() > Anabatic::Session::getSliceHeight())
|
|
|
|
and (_gcell->getHeight() > Anabatic::Session::getSliceHeight()) ) {
|
|
|
|
_gcell->doGrid();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cdebug_log(535,0) << "> Device:" << _instance << endl;
|
|
|
|
cdebug_log(535,0) << "> GCell: " << _gcell << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DSlicingNode::isSame ( SlicingNode* node, unsigned int flags ) const
|
|
|
|
{
|
|
|
|
bool isSame = _nodeSets->compare( node->getNodeSets(), flags );
|
|
|
|
if ( not isSame and (flags & ShowDiff) )
|
|
|
|
cerr << "DSlicingNode::isSame() Check " << this << " vs. " << node << endl;
|
|
|
|
return isSame;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DSlicingNode::isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const
|
|
|
|
{
|
|
|
|
bool isSame = _nodeSets->compare( node->getNodeSets(), flags );
|
|
|
|
if (not isSame and (flags & ShowDiff))
|
|
|
|
cerr << Warning( "DSlicingNode::isSymmetric(): Different nodesets Check %s vs. %s."
|
|
|
|
, getString(this).c_str(), getString(node).c_str() ) << endl;
|
|
|
|
|
|
|
|
if (_instance) {
|
|
|
|
Cell* model1 = _instance->getMasterCell();
|
|
|
|
Cell* model2 = node->getInstance()->getMasterCell();
|
|
|
|
Device* device1 = dynamic_cast<Device*>( model1 );
|
|
|
|
Device* device2 = dynamic_cast<Device*>( model2 );
|
|
|
|
|
|
|
|
if (device1 and device2) {
|
|
|
|
CommonSourcePair* csp1 = dynamic_cast<CommonSourcePair*>( model1 );
|
|
|
|
DifferentialPair* dp1 = dynamic_cast<DifferentialPair*>( model1 );
|
|
|
|
Transistor* ts1 = dynamic_cast<Transistor* >( model1 );
|
|
|
|
|
|
|
|
CommonSourcePair* csp2 = dynamic_cast<CommonSourcePair*>( model2 );
|
|
|
|
DifferentialPair* dp2 = dynamic_cast<DifferentialPair*>( model2 );
|
|
|
|
Transistor* ts2 = dynamic_cast<Transistor* >( model2 );
|
|
|
|
|
|
|
|
if (csp1 and csp2) isSame = csp1->isSame( csp2 );
|
|
|
|
else if (dp1 and dp2 ) isSame = dp1 ->isSame( dp2 );
|
|
|
|
else if (ts1 and ts2 ) isSame = ts1 ->isSame( ts2 );
|
|
|
|
else isSame = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not isSame)
|
|
|
|
cerr << Warning( "DSlicingNode::isSymmetric(): Different devices. Check %s vs. %s."
|
|
|
|
, getString(this).c_str(), getString(node).c_str() ) << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return isSame;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::updateMatrixGCellPosition ()
|
|
|
|
{
|
|
|
|
DbU::Unit tx = getX() -_gcell->getXMin();
|
|
|
|
DbU::Unit ty = getY() -_gcell->getYMin();
|
|
|
|
Anabatic::GCell* ygcell = _gcell;
|
|
|
|
Anabatic::GCell* xgcell = ygcell;
|
|
|
|
|
|
|
|
while ( ygcell ) {
|
|
|
|
while ( xgcell ) {
|
|
|
|
xgcell->setSouthWestCorner( xgcell->getXMin() + tx, xgcell->getYMin() + ty );
|
|
|
|
if (xgcell->getEast()->isMatrix()) xgcell = xgcell->getEast();
|
|
|
|
else xgcell = NULL;
|
|
|
|
}
|
|
|
|
if (ygcell->getNorth()->isMatrix()) ygcell = ygcell->getNorth();
|
|
|
|
else ygcell = NULL;
|
|
|
|
xgcell = ygcell;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::updateMatrixGContacts ()
|
|
|
|
{
|
|
|
|
Anabatic::GCell* ygcell = _gcell;
|
|
|
|
Anabatic::GCell* xgcell = ygcell;
|
|
|
|
|
|
|
|
while ( ygcell ) {
|
|
|
|
while ( xgcell ) {
|
|
|
|
xgcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
if (xgcell->getEast()->isMatrix()) xgcell = xgcell->getEast();
|
|
|
|
else xgcell = NULL;
|
|
|
|
}
|
|
|
|
if (ygcell->getNorth()->isMatrix()) ygcell = ygcell->getNorth();
|
|
|
|
else ygcell = NULL;
|
|
|
|
xgcell = ygcell;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::updateGCellPosition ()
|
|
|
|
{
|
|
|
|
cdebug_log(535,0) << "DSlicingNode::updateGCellPosition() " << _gcell << endl;
|
|
|
|
|
|
|
|
if (_gcell) {
|
|
|
|
if (_parent) {
|
|
|
|
if (_parent->getType() == HorizontalSNode) {
|
|
|
|
DbU::Unit hpitch = _rg->getHorizontalPitch();
|
|
|
|
|
|
|
|
if (getAlignment() == AlignLeft) {
|
|
|
|
_gcell->getEastNMatrix()->setSouthWestCorner( getX()+getWidth(), getY() );
|
|
|
|
_gcell->getEastNMatrix()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/hpitch)
|
|
|
|
, floor(getHeight()/hpitch)
|
|
|
|
);
|
|
|
|
} else if (getAlignment() == AlignCenter) {
|
|
|
|
_gcell->getWest()->setSouthWestCorner( _parent->getX(), getY() );
|
|
|
|
_gcell->getWest()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/(2*hpitch))
|
|
|
|
, floor(getHeight()/(2*hpitch))
|
|
|
|
);
|
|
|
|
|
|
|
|
_gcell->getEastNMatrix()->setSouthWestCorner( getX()+getWidth(), getY() );
|
|
|
|
_gcell->getEastNMatrix()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/(2*hpitch))
|
|
|
|
, floor(getHeight()/(2*hpitch))
|
|
|
|
);
|
|
|
|
} else if (getAlignment() == AlignRight) {
|
|
|
|
_gcell->getWest()->setSouthWestCorner( _parent->getX(), getY() );
|
|
|
|
_gcell->getWest()->forceEdgesCapacities( floor((_parent->getWidth()-getWidth())/hpitch)
|
|
|
|
, floor(getHeight()/hpitch)
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
} else if (_parent->getType() == VerticalSNode) {
|
|
|
|
DbU::Unit vpitch = _rg->getVerticalPitch();
|
|
|
|
|
|
|
|
if (getAlignment() == AlignBottom) {
|
|
|
|
_gcell->getNorthNMatrix()->setSouthWestCorner( getX(), getY()+getHeight() );
|
|
|
|
_gcell->getNorthNMatrix()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/vpitch)
|
|
|
|
, floor(getWidth()/vpitch)
|
|
|
|
);
|
|
|
|
} else if (getAlignment() == AlignCenter) {
|
|
|
|
_gcell->getSouth()->setSouthWestCorner( getX(), _parent->getY() );
|
|
|
|
_gcell->getSouth()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/(2*vpitch))
|
|
|
|
, floor(getWidth()/(2*vpitch))
|
|
|
|
);
|
|
|
|
|
|
|
|
_gcell->getNorthNMatrix()->setSouthWestCorner( getX(), getY()+getHeight() );
|
|
|
|
_gcell->getNorthNMatrix()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/(2*vpitch))
|
|
|
|
, floor(getWidth()/(2*vpitch))
|
|
|
|
);
|
|
|
|
} else if (getAlignment() == AlignTop) {
|
|
|
|
_gcell->getSouth()->setSouthWestCorner( getX(), _parent->getY() );
|
|
|
|
_gcell->getSouth()->forceEdgesCapacities( floor((_parent->getHeight()-getHeight())/vpitch)
|
|
|
|
, floor(getWidth()/vpitch)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_gcell->isMatrix()) updateMatrixGCellPosition();
|
|
|
|
else _gcell->setSouthWestCorner( getX(), getY() );
|
|
|
|
cdebug_log(535,0) << "| Updated:" << _gcell << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::updateGContacts ()
|
|
|
|
{
|
|
|
|
cdebug_log(535,0) << "DSlicingNode::updateGContacts() " << _gcell << endl;
|
|
|
|
|
|
|
|
if (_gcell) {
|
|
|
|
if (_parent) {
|
|
|
|
if (_parent->getType() == HorizontalSNode) {
|
|
|
|
if (getAlignment() == AlignLeft) {
|
|
|
|
_gcell->getEastNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
} else if (getAlignment() == AlignCenter) {
|
|
|
|
_gcell->getWest()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
_gcell->getEastNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
} else if (getAlignment() == AlignRight) {
|
|
|
|
_gcell->getWest()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
}
|
|
|
|
} else if (_parent->getType() == VerticalSNode) {
|
|
|
|
if (getAlignment() == AlignBottom) {
|
|
|
|
_gcell->getNorthNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
} else if (getAlignment() == AlignCenter) {
|
|
|
|
_gcell->getSouth()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
_gcell->getNorthNMatrix()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
} else if (getAlignment() == AlignTop) {
|
|
|
|
_gcell->getSouth()->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_gcell->isMatrix()) updateMatrixGContacts();
|
|
|
|
else _gcell->updateGContacts( Anabatic::Flags::Vertical|Anabatic::Flags::Horizontal );
|
|
|
|
|
|
|
|
cdebug_log(535,0) << "| Updated:" << _gcell << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::restrictDevices ()
|
|
|
|
{
|
|
|
|
if (_gcell) {
|
|
|
|
Anabatic::Vertex* vertex = _gcell->getObserver< Anabatic::Vertex>( Anabatic::GCell::Observable::Vertex );
|
|
|
|
vertex->setRestricted();
|
|
|
|
|
|
|
|
if (not vertex->hasValidStamp()) {
|
|
|
|
if ( (_gcell->getWidth() > _gcell->getHeight())
|
|
|
|
or (_gcell->getWidth() == _gcell->getHeight()) ) {
|
|
|
|
vertex->unsetFlags( Anabatic::Vertex::iVertical );
|
|
|
|
vertex->setFlags ( Anabatic::Vertex::iHorizontal );
|
|
|
|
} else {
|
|
|
|
vertex->unsetFlags( Anabatic::Vertex::iHorizontal );
|
|
|
|
vertex->setFlags ( Anabatic::Vertex::iVertical );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::printLine () const
|
|
|
|
{
|
|
|
|
cerr << "Instance: " << _instance << ", ";
|
|
|
|
SlicingNode::printLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string DSlicingNode::_getString () const
|
|
|
|
{
|
|
|
|
string s = Super::_getString();
|
|
|
|
s.insert( s.size()-1, " "+getString(_instance->getName()));
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string DSlicingNode::_getTypeName () const
|
|
|
|
{ return "DSlicingNode"; }
|
|
|
|
|
|
|
|
|
|
|
|
bool DSlicingNode::isAnalog () const
|
|
|
|
{
|
|
|
|
if (not _instance) return false;
|
|
|
|
return dynamic_cast<Device*>(_instance->getMasterCell() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DSlicingNode::isDigital () const
|
|
|
|
{ return not isAnalog(); }
|
|
|
|
|
|
|
|
|
|
|
|
bool DSlicingNode::checkCellInstances ( Cell* cell )
|
|
|
|
{
|
|
|
|
if (not _instance) return false;
|
|
|
|
return cell->getInstance(_instance->getName());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DSlicingNode::resetWireOccupation ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
} // Bora namespace.
|