coriolis/bora/src/HVSlicingNode.cpp

1328 lines
41 KiB
C++
Raw Normal View History

Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
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 : "./HVSlicingNode.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/NetRoutingProperty.h"
#include "hurricane/analog/Device.h"
#include "katana/KatanaEngine.h"
#include "bora/HVSlicingNode.h"
#include "bora/HSlicingNode.h"
#include "bora/VSlicingNode.h"
#include "bora/DSlicingNode.h"
#include "bora/RHVSlicingNode.h"
namespace Bora {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Point;
using Hurricane::Box;
using Hurricane::RoutingPad;
using Hurricane::NetRoutingState;
using Hurricane::NetRoutingExtension;
using Analog::Device;
// -------------------------------------------------------------------
// Class : "Bora::HVSlicingNode".
HVSlicingNode::HVSlicingNode ( unsigned int type, unsigned int alignment )
: Super( type, NodeSets::create(), alignment, NULL )
, _children ()
, _toleranceRatioH(0)
, _toleranceRatioW(0)
, _toleranceBandH (0)
, _toleranceBandW (0)
, _symmetries ()
, _slicingRouting ()
, _netSymmetries ()
{ }
HVSlicingNode::~HVSlicingNode ()
{ }
DbU::Unit HVSlicingNode::getToleranceRatioH () const
{ return _toleranceRatioH; }
DbU::Unit HVSlicingNode::getToleranceRatioW () const
{ return _toleranceRatioW; }
DbU::Unit HVSlicingNode::getToleranceBandH () const
{ return _toleranceBandH; }
DbU::Unit HVSlicingNode::getToleranceBandW () const
{ return _toleranceBandW; }
void HVSlicingNode::setToleranceRatioH ( DbU::Unit tolerance )
{
_toleranceRatioH = tolerance;
getRoot()->_resetSlicingTree();
}
void HVSlicingNode::setToleranceRatioW ( DbU::Unit tolerance )
{
_toleranceRatioW = tolerance;
getRoot()->_resetSlicingTree();
}
void HVSlicingNode::setToleranceBandH ( DbU::Unit tolerance )
{
_toleranceBandH = tolerance;
resetSlicingTree();
}
void HVSlicingNode::setToleranceBandW ( DbU::Unit tolerance )
{
_toleranceBandW = tolerance;
resetSlicingTree();
}
void HVSlicingNode::recursiveSetToleranceRatioH ( DbU::Unit tolerance )
{
_recursiveSetToleranceRatioH( tolerance );
getRoot()->_resetSlicingTree();
}
void HVSlicingNode::recursiveSetToleranceRatioW ( DbU::Unit tolerance )
{
_recursiveSetToleranceRatioW( tolerance );
getRoot()->_resetSlicingTree();
}
void HVSlicingNode::recursiveSetToleranceBandH ( DbU::Unit tolerance )
{
resetSlicingTree();
_recursiveSetToleranceBandH( tolerance );
}
void HVSlicingNode::recursiveSetToleranceBandW ( DbU::Unit tolerance )
{
resetSlicingTree();
_recursiveSetToleranceBandW( tolerance );
}
void HVSlicingNode::_recursiveSetToleranceRatioH ( DbU::Unit tolerance )
{
for ( SlicingNode* node : _children ) {
if ( (not node->isDevice()) and (not node->isRouting()) )
node->recursiveSetToleranceRatioH( tolerance );
}
_toleranceRatioH = tolerance;
}
void HVSlicingNode::_recursiveSetToleranceRatioW ( DbU::Unit tolerance )
{
for ( SlicingNode* node : _children ) {
if ( (not node->isDevice()) and (not node->isRouting()) )
node->recursiveSetToleranceRatioW( tolerance );
}
_toleranceRatioW = tolerance;
}
void HVSlicingNode::_recursiveSetToleranceBandH ( DbU::Unit tolerance )
{
for ( SlicingNode* node : _children ) {
if ( (not node->isDevice()) and (not node->isRouting()) )
node->recursiveSetToleranceBandH( tolerance );
}
_toleranceBandH = tolerance;
}
void HVSlicingNode::_recursiveSetToleranceBandW ( DbU::Unit tolerance )
{
for ( SlicingNode* node : _children ) {
if ( (not node->isDevice()) and (not node->isRouting()) )
node->recursiveSetToleranceBandW( tolerance );
}
_toleranceBandW = tolerance;
}
void HVSlicingNode::setTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw )
{
resetSlicingTree();
_toleranceRatioH = trh;
_toleranceRatioW = trw;
_toleranceBandH = tbh;
_toleranceBandW = tbw;
}
void HVSlicingNode::recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw )
{
resetSlicingTree();
_recursiveSetTolerances( trh, trw, tbh, tbw );
}
void HVSlicingNode::_recursiveSetTolerances ( DbU::Unit trh, DbU::Unit trw, DbU::Unit tbh, DbU::Unit tbw )
{
_recursiveSetToleranceRatioH(trh);
_recursiveSetToleranceRatioW(trw);
_recursiveSetToleranceBandH (tbh);
_recursiveSetToleranceBandW (tbw);
}
bool HVSlicingNode::hasEmptyChildrenNodeSets () const
{
// WARNING: The original code was nonsensical, have to check it.
for ( SlicingNode* node : _children ) {
NodeSets* ns = node->getNodeSets();
if (ns->empty() and not node->isRouting() )
return true;
}
return false;
}
size_t HVSlicingNode::getChildIndex ( SlicingNode* node ) const
{
for ( size_t i=0 ; i<_children.size() ; ++i ) {
if ( (_children[i]->getType() == node->getType() )
and (_children[i]->getHeight() == node->getHeight())
and (_children[i]->getWidth () == node->getWidth ())
and (_children[i]->getX() == node->getX() )
and (_children[i]->getY() == node->getY() ) )
return i;
}
return NodeSets::NotFound;
}
SlicingNode* HVSlicingNode::getChild ( size_t index ) const
{ return _children[index]; }
void HVSlicingNode::createChild ( unsigned int type, unsigned int alignment )
{
if (type == HorizontalSNode) {
HSlicingNode* hsn = HSlicingNode::create( alignment );
hsn->setTolerances( getToleranceRatioH()
, getToleranceRatioW()
, getToleranceBandH ()
, getToleranceBandW ()
);
push_back( hsn );
resetSlicingTree();
} else if (type == VerticalSNode) {
VSlicingNode* vsn = VSlicingNode::create( alignment );
vsn->setTolerances( getToleranceRatioH()
, getToleranceRatioW()
, getToleranceBandH ()
, getToleranceBandW ()
);
push_back( vsn );
resetSlicingTree();
}
else
cerr << Warning( "HVSlicingNode::createChild(SlicingType, Alignment): Unknown type." ) << endl;
}
void HVSlicingNode::createChild ( NodeSets* nodeSets
, unsigned int alignment
, Instance* instance
, BoxSet* boxSet
)
{
DSlicingNode* node = DSlicingNode::create( nodeSets, alignment, instance, boxSet );
node->setParent( this );
push_back( node );
resetSlicingTree();
}
void HVSlicingNode::createChild ( size_t childIndex, size_t copyIndex, unsigned int tr )
{
if (childIndex != copyIndex) {
SlicingNode* node = this->getChild( childIndex )->clone(tr);
insertNode( node, copyIndex );
_symmetries.push_back( Symmetry( min(childIndex, copyIndex), max(childIndex, copyIndex) ) );
resetSlicingTree();
normalizeSymmetries();
}
else
cerr << Warning( "HVSlicingNode::createChild(size_t,size_t, unsigned int): Indexes cannot be the same." ) << endl;
}
void HVSlicingNode::insertNode ( SlicingNode* node, size_t index )
{
vector<SlicingNode*>::iterator it = _children.begin();
for ( size_t i=0; i < index; i++ ) { if (it != _children.end()) ++it; }
_children.insert( it, node );
node->setParent( this );
resetSlicingTree();
}
void HVSlicingNode::push_back ( SlicingNode* node, bool reset )
{
node->setParent( this );
_children.push_back( node );
if (reset) resetSlicingTree();
}
void HVSlicingNode::push_front ( SlicingNode* node )
{
node->setParent( this );
_children.insert( _children.begin(), node );
resetSlicingTree();
}
void HVSlicingNode::removeNode ( SlicingNode* node )
{
size_t index = 0;
for ( VSlicingNodes::iterator inode = _children.begin()
; inode != _children.end()
; ++inode, ++index ) {
if ((*inode) == node) {
_children.erase( inode );
removeSymmetry( index );
resetSlicingTree();
node->removeParent();
node->setX ( 0 );
node->setY ( 0 );
node->setPlaced ( false );
return;
}
}
}
bool HVSlicingNode::isSymmetry ( size_t index, Symmetry& symmetry )
{
if (_symmetries.empty()) return false;
for ( LSymmetries::iterator isym=_symmetries.begin() ; isym != _symmetries.end() ; ++isym ) {
if ((*isym).second == index) {
symmetry = Symmetry( (*isym) );
return true;
}
}
return false;
}
bool HVSlicingNode::isSymmetry ( size_t index )
{
if (_symmetries.empty()) return false;
for ( Symmetry& sym : _symmetries ) {
if (sym.second == index) return true;
}
return false;
}
void HVSlicingNode::addSymmetry ( size_t childIndex, size_t copyIndex, bool reset )
{
if (childIndex >= getChildren().size()) {
cerr << Warning( "HVSlicingNode::addSymmetry(size_t,size_t): Child index out of range %d (> %d), symmetry is ignored."
, childIndex, getChildren().size() ) << endl;
return;
}
if (copyIndex >= getChildren().size()) {
cerr << Warning( "HVSlicingNode::addSymmetry(size_t,size_t): Copy index out of range %d (> %d), symmetry is ignored."
, copyIndex, getChildren().size() ) << endl;
return;
}
if (childIndex == copyIndex) {
cerr << Warning( "HVSlicingNode::addSymmetry(size_t,size_t): Indexes cannot be identical (%d), symmetry is ignored."
, childIndex ) << endl;
return;
}
unsigned int symmetryType = 0;
if (getType() == HorizontalSNode) symmetryType = HSymmetry;
if (getType() == VerticalSNode ) symmetryType = VSymmetry;
if (not getChild(childIndex)->isSymmetric(getChild(copyIndex), symmetryType, ShowDiff)) {
cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored.\n"
" child %d: %s\n"
" child %d: %s"
, childIndex, copyIndex
, childIndex, getString(getChild(childIndex)).c_str()
, copyIndex , getString(getChild( copyIndex)).c_str()
) << endl;
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
return;
}
_symmetries.push_back( Symmetry( min(childIndex, copyIndex), max(childIndex, copyIndex) ) );
if (reset) resetSlicingTree();
unsigned int flag = 0;
if (getType() == HorizontalSNode) flag = HSymmetry;
if (getType() == VerticalSNode ) flag = VSymmetry;
getChild(copyIndex)->setSymmetryFlag( flag );
getChild( copyIndex )->setMaster(getChild( childIndex ));
normalizeSymmetries();
}
void HVSlicingNode::removeSymmetry ( size_t index )
{
bool first = true;
bool isReference = true;
size_t erasedFirst = 0;
size_t erasedSecond = 0;
for ( LSymmetries::iterator it = _symmetries.begin(); it != _symmetries.end(); it++ ) {
if ( ( ((*it).first == index) or ((*it).second == index)) and first ) {
LSymmetries::iterator itToerase = it;
it++;
resetSlicingTree();
first = false;
if ((*it).first == index){
erasedFirst = (*itToerase).first;
erasedSecond = (*itToerase).second;
} else
isReference = false;
_symmetries.erase(itToerase);
it--;
} else {
if ( not first and isReference ) {
if ((*it).first == erasedFirst) (*it).first = erasedSecond;
}
if ((*it).first > index) (*it).first--;
if ((*it).second > index) (*it).second--;
}
}
}
void HVSlicingNode::normalizeSymmetries ()
{
// Notes :
// Symmetries must be described in a specific way, in case it is not, this method correct it.
// Examples:
// WRONG: Symmetries [< 1, 2 >, < 2, 3 >, < 3, 4 >]; RIGHT: [< 1, 2 >, < 1, 3 >, < 1, 4 >];
// WRONG: Symmetries [< 3, 4 >, < 5, 6 >, < 1, 2 >]; RIGHT: [< 1, 2 >, < 3, 4 >, < 5, 6 >];
// WRONG: Symmetries [< 1, 2 >, < 1, 2 >, < 3, 4 >]; RIGHT: [< 1, 2 >, < 3, 4 >];
LSymmetries adjustedSymmetries;
for ( Symmetry& sym : _symmetries ) {
if (sym.first > sym.second) adjustedSymmetries.push_back( Symmetry( sym.second, sym.first ) );
else adjustedSymmetries.push_back( Symmetry( sym.first , sym.second ) );
}
adjustedSymmetries.sort();
for ( LSymmetries::iterator isym = adjustedSymmetries.begin()
; isym != adjustedSymmetries.end()
; isym++ ) {
for ( LSymmetries::iterator idup = isym
; idup != adjustedSymmetries.end()
; idup++ ) {
if (idup == isym) continue;
if ((*isym).second == (*idup).first) (*idup).first = (*isym).first;
if ((*isym).second < (*idup).first) break;
}
}
_symmetries = adjustedSymmetries;
}
void HVSlicingNode::_resetSlicingTree ()
{
_x = 0;
_y = 0;
setPlaced( false );
if (not isPreset()) {
_boxSet = NULL;
setSet( false );
for ( SlicingNode* child : _children ) child->_resetSlicingTree();
}
}
void HVSlicingNode::print () const
{
SlicingNode::print();
if (not _symmetries.empty()) {
cerr << "Symmetries: " << endl;
for ( const Symmetry& sym : _symmetries )
cerr << "Children: " << sym.first << " and " << sym.second << endl;
cerr << endl;
} else
cerr << "Symmetries: None" << endl;
if (not _slicingRouting.empty()) {
cerr<< "Slicing Routing: " << endl;
size_t index = 0;
for ( const RHVSlicingNode* node : _slicingRouting ) {
cerr << "---------------- " << setprecision(4) << index << " -----------------" << endl;
cerr << "Print - Slicing Routing: ";
cerr << "X: " << DbU::getPhysical(node->getX (), DbU::Micro);
cerr << ", Y: " << DbU::getPhysical(node->getY (), DbU::Micro);
cerr << ", height: " << DbU::getPhysical(node->getHeight(), DbU::Micro);
cerr << ", width: " << DbU::getPhysical(node->getWidth (), DbU::Micro) << endl;
cerr << "GCell: " << node->getGCell() << endl;
if(node->getGCell()){
cerr << "GCell : " << node->getGCell() << endl;
cerr << "Edges : " << endl;
for ( const Anabatic::Edge* edge : node->getGCell()->getNorthEdges() )
cerr << edge->getOpposite(node->getGCell()) << endl;
for ( const Anabatic::Edge* edge : node->getGCell()->getSouthEdges() )
cerr << edge->getOpposite(node->getGCell()) << endl;
for ( const Anabatic::Edge* edge : node->getGCell()->getEastEdges() )
cerr << edge->getOpposite(node->getGCell()) << endl;
for ( const Anabatic::Edge* edge : node->getGCell()->getWestEdges() )
cerr << edge->getOpposite(node->getGCell()) << endl;
}
cerr << "------------------------------------" << endl;
++index;
}
} else
cerr << "Slicing Routing: empty" << endl;
cerr << endl;
}
void HVSlicingNode::printChildren () const
{
size_t index = 0;
for ( const SlicingNode* child : _children ) {
if ( child->isDevice() or child->isRouting() ) {
cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl;
child->print();
} else {
cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl;
child->print();
child->printChildren();
}
++index;
}
}
void HVSlicingNode::printLine () const
{
SlicingNode::printLine();
if (not _symmetries.empty()) {
cerr << "Symmetries: " << endl;
for ( const Symmetry& sym : _symmetries )
cerr << "Children: " << sym.first << " and " << sym.second << endl;
cerr << endl;
}
}
void HVSlicingNode::printChildrenLine () const
{
size_t index = 0;
for ( const SlicingNode* child : _children ) {
if ( child->isDevice() or child->isRouting() ) {
cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl;
child->printLine();
} else {
cerr << endl;
cerr << "-- Children: " << index << "/" << _children.size()-1 << " --" << endl;
child->printLine();
child->printChildrenLine();
}
++index;
}
}
bool HVSlicingNode::recursiveCheckPreset () const
{
bool preset = isPreset();
if (preset) {
for ( const SlicingNode* child : _children ) preset = child->recursiveCheckPreset();
}
return preset;
}
bool HVSlicingNode::recursiveCheckSet () const
{
bool rset = isSet();
if (rset) {
for ( const SlicingNode* child : _children ) rset = child->recursiveCheckSet();
}
return rset;
}
bool HVSlicingNode::recursiveCheckPlaced () const
{
bool placed = isPlaced();
if (placed) {
for ( const SlicingNode* child : _children ) placed = child->recursiveCheckPlaced();
}
return placed;
}
int HVSlicingNode::getLeafNumber() const
{
int leafs = 0;
for ( const SlicingNode* child : _children ) leafs += child->getLeafNumber();
return leafs;
}
double HVSlicingNode::getDevicesArea () const
{
double area = 0.0;
for ( const SlicingNode* child : _children ) area += child->getDevicesArea();
return area;
}
double HVSlicingNode::getOccupationArea () const
{
double estimation = 0;
if (recursiveCheckPlaced())
estimation = (100 * getDevicesArea()) / (getHeight() * getWidth());
else
cerr << Warning( "HVSlicingNode::getSpaceEstimation()): SlicingNodes dimensions need to be set first before being estimated." ) << endl;
return estimation;
}
void HVSlicingNode::setGlobalSize ( DbU::Unit height, DbU::Unit width )
{
if (not _nodeSets->empty()) {
DbU::Unit bestH = 0;
DbU::Unit bestW = 0;
DbU::Unit currentH = 0;
DbU::Unit currentW = 0;
BoxSet* boxSet = _nodeSets->at( 0 );
for ( BoxSet* bs : _nodeSets->getBoxSets() ) {
currentH = bs->getHeight();
currentW = bs->getWidth();
if ( (currentH <= height) and (currentW <= width) ) {
if ( ((height-currentH) <= _toleranceRatioH) and ((height-bestH) <= _toleranceRatioH) ) {
if (currentW > bestW) {
bestH = currentH;
bestW = currentW;
boxSet = bs;
}
} else if (currentH > bestH) {
bestH = currentH;
bestW = currentW;
boxSet = bs;
}
}
}
_setGlobalSize( boxSet );
} else
cerr << Warning( "HVSlicingNode::setGlobalSize(DbU::Unit h, DbU::Unit w): NodeSets empty. UpdateGlobalSize needs to be used first or with higher tolerances." ) << endl;
}
void HVSlicingNode::setGlobalSize ( size_t index )
{
if (not _nodeSets->empty()) {
if (index+1 > _nodeSets->size())
cerr << Warning( "HVSlicingNode::setGlobalSize(size_t): Out of bound index." ) << endl;
else
_setGlobalSize( _nodeSets->at(index) );
} else
cerr << Warning( "HVSlicingNode::setGlobalSize(size_t): NodeSets empty. UpdateGlobalSize needs to be used first or with higher tolerances." ) << endl;
}
void HVSlicingNode::_setGlobalSize ( BoxSet* boxSet )
{
if (not isPreset()) {
if (not getMaster())
_setBoxSet( boxSet );
else
_setBoxSet( _master->getBoxSet() );
if ( ((getType() == HorizontalSNode) and (isHSymmetry()))
or ((getType() == VerticalSNode ) and (isVSymmetry())) ) {
vector<BoxSet*>::const_iterator ibs = boxSet->getSet().begin();
for ( VSlicingNodes::reverse_iterator ichild = _children.rbegin()
; ichild != _children.rend(); ++ichild ) {
(*ichild)->_setGlobalSize( *ibs );
ibs++;
}
} else {
vector<BoxSet*>::const_iterator ibs = boxSet->getSet().begin();
for ( VSlicingNodes::iterator ichild = _children.begin()
; ichild != _children.end(); ichild++) {
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
(*ichild)->_setGlobalSize( *ibs );
ibs++;
}
}
}
}
void HVSlicingNode::preDestroy ()
{
Super::preDestroy();
for ( SlicingNode* child : _children ) child->removeParent();
}
void HVSlicingNode::destroy ()
{
HVSlicingNode::preDestroy();
delete this;
}
void HVSlicingNode::preRecursiveDestroy ()
{
Super::preRecursiveDestroy();
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) {
child->removeParent();
child->recursiveDestroy();
} else {
child->removeParent();
child->destroy();
}
}
}
void HVSlicingNode::recursiveDestroy ()
{
HVSlicingNode::preRecursiveDestroy();
delete this;
}
LSlicingNodes HVSlicingNode::getLeaves ()
{
LSlicingNodes leaves;
for ( SlicingNode* child : _children ) {
if ( (child->getType() == DeviceSNode) or (child->getType() == RoutingSNode) )
leaves.push_back( child );
else
leaves.splice( leaves.end(), child->getLeaves() );
}
return leaves;
}
bool HVSlicingNode::checkInitialPlacement ( int& cpt ) const
{
// Notes::
// Initial placement criteria is having at least 2 devices placed at (x,y) = (0,0)
bool initialPlacement = false;
if (cpt < 2) {
initialPlacement = true;
for ( const SlicingNode* child : _children ) {
if (cpt < 2) initialPlacement = child->checkInitialPlacement( cpt );
}
}
return initialPlacement;
}
bool HVSlicingNode::isSame ( SlicingNode* node, unsigned int flags ) const
{
if ( (getType() == node->getType() )
and (getNbChild() == node->getNbChild() )
and (getToleranceBandH() == node->getToleranceBandH())
and (getToleranceBandW() == node->getToleranceBandW()) ) {
bool isSame = true;
for ( size_t ichild = 0 ; isSame and (ichild < getNbChild()) ; ++ichild ) {
isSame = getChild(ichild)->isSame( node->getChild(ichild) );
}
if (not isSame and (flags & ShowDiff))
cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs (childs)." << endl;
return isSame;
} else {
if (flags & ShowDiff)
cerr << "HVSlicingNode::isSame() " << this << " and " << node << " differs." << endl;
return false;
}
}
bool HVSlicingNode::checkCellInstances ( Cell* cell )
{
if (not cell) {
cerr << Warning( "HVSlicingNode::checkCellInstances(): Cell is NULL." ) << endl;
return false;
}
for ( SlicingNode* child : _children ) {
if (not child->checkCellInstances(cell)) return false;
}
return true;
}
SlicingNode* HVSlicingNode::findInstance ( Instance* instance )
{
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) {
SlicingNode* node = child->findInstance( instance );
if (node) return node;
} else if (child->getType() == DeviceSNode) {
if ( child->getInstance() == instance )
return child;
}
}
return NULL;
}
SlicingNode* HVSlicingNode::findSlicingNode ( Anabatic::GCell* gcell )
{
if (getGCell() == gcell) return this;
for ( RHVSlicingNode* node : _slicingRouting ) {
if (node->getGCell() == gcell) return node;
}
for ( SlicingNode* child : _children ) {
if( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) {
SlicingNode* node = child->findSlicingNode( gcell );
if (node) return node;
} else if (child->getType() == DeviceSNode) {
if (child->getGCell() == gcell)
return child;
}
}
return NULL;
}
void HVSlicingNode::resetSlicingRouting ()
{
for ( RHVSlicingNode* node : _slicingRouting ) node->resetSize();
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
child->resetSlicingRouting();
}
setRoutingEstimated(0);
}
void HVSlicingNode::destroySlicingRouting ()
{
for ( RHVSlicingNode* node : _slicingRouting ) node->destroy();
_slicingRouting.clear();
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
child->destroySlicingRouting();
}
setRoutingEstimated(0);
}
size_t HVSlicingNode::getRoutingIndex ( SlicingNode* node ) const
{
size_t index = 0;
for ( const RHVSlicingNode* node : _slicingRouting ) {
if ( (node->getHeight() == node->getHeight())
and (node->getWidth () == node->getWidth ())
and (node->getX () == node->getX ())
and (node->getY () == node->getY ()) )
return index;
++index;
}
return NodeSets::NotFound;
}
SlicingNode* HVSlicingNode::getSlicingRouting ( size_t index ) const
{ return _slicingRouting.at( index ); }
void HVSlicingNode::restrictDevices ()
{
for ( SlicingNode* child : _children ) child->restrictDevices();
for ( RHVSlicingNode* node : _slicingRouting ) node ->restrictDevices();
}
void HVSlicingNode::setVertexRestriction ( Net* net, Katana::KatanaEngine* katana )
{
cdebug_log(536,1) << "HVSlicingNode::setVertexRestriction(Net*,KatanaEngine*)" << endl;
restrictDevices();
vector<RoutingPad*> rps;
for ( RoutingPad* rp : net->getRoutingPads() ) rps.push_back( rp );
for ( RoutingPad* rp : rps ) {
Box rpBb = rp->getBoundingBox();
Point center = rpBb.getCenter();
Anabatic::GCell* gcell = katana->getGCellUnder( center );
if (not gcell) {
cerr << Error( "HVSlicingNode::setVetexRestriction(): %s of %s is not under any GCell.\n"
" It will be ignored ans the routing will be incomplete."
, getString(rp ).c_str()
, getString(net).c_str()
) << endl;
continue;
}
Anabatic::Vertex* vertex = gcell->getObserver<Anabatic::Vertex>(Anabatic::GCell::Observable::Vertex);
// Analog Restrictions
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
Cell* cell = plug->getInstance()->getMasterCell();
Device* device = dynamic_cast<Device*>( cell );
if (device) {
cdebug_log(536,0) << "Underlying device: " << device << endl;
unsigned int rule = device->getRestrictions2(plug->getMasterNet());
vertex->clearRestriction();
cdebug_log(536,0) << "Restrictions rule: " << rule << endl;
if (rule & WestBlocked ) vertex->setWRestricted();
if (rule & EastBlocked ) vertex->setERestricted();
if (rule & SouthBlocked) vertex->setSRestricted();
if (rule & NorthBlocked) vertex->setNRestricted();
cdebug_log(536,0) << "Applied restrictions: " << vertex << endl;
} else {
vertex->clearRestriction();
}
}
cdebug_tabw(536,-1);
}
void HVSlicingNode::estimateChannelsSize ()
{
for ( RHVSlicingNode* node : _slicingRouting ) node ->estimateChannelsSize();
for ( SlicingNode* child : _children ) child->estimateChannelsSize();
}
void HVSlicingNode::expandRoutingChannel ()
{
estimateChannelsSize();
_expandRoutingChannel();
}
void HVSlicingNode::_expandRoutingChannel ()
{
for ( RHVSlicingNode* node : _slicingRouting ) node->_expandRoutingChannel();
for ( SlicingNode* child : _children ) {
if (child->getType() != RoutingSNode) child->_expandRoutingChannel();
}
setRoutingEstimated(RoutingEstimated);
if (not _parent) {
for ( SlicingNode* child : _children ) child->adjustBorderChannels();
}
}
void HVSlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width )
{
for ( RHVSlicingNode* node : _slicingRouting ) node->expandRoutingChannel( height, width );
for ( SlicingNode* child : _children ) {
if (child->getType() != RoutingSNode) child->expandRoutingChannel( height, width );
}
setRoutingEstimated( RoutingEstimated );
if (_parent == NULL)
for ( SlicingNode* child : _children ) child->adjustBorderChannels();
}
bool HVSlicingNode::isRoutingEstimated () const
{
bool estimated = true;
if (_slicingRouting.empty()){
estimated = false;
} else {
for ( RHVSlicingNode* node : _slicingRouting ) estimated &= node->isRoutingEstimated();
}
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode ) or (child->getType() == VerticalSNode) )
estimated &= child->isRoutingEstimated();
}
return estimated;
}
void HVSlicingNode::updateGCellPosition ()
{
cdebug_log(535,1) << "HVSlicingNode::updateGCellPosition()" << endl;
for ( SlicingNode* node : _slicingRouting ) node ->updateGCellPosition();
for ( SlicingNode* child : _children ) child->updateGCellPosition();
cdebug_tabw(535,-1);
}
void HVSlicingNode::updateGContacts ()
{
cdebug_log(535,1) << "HVSlicingNode::updateGContacts()" << endl;
for ( SlicingNode* node : _slicingRouting ) node ->updateGContacts();
for ( SlicingNode* child : _children ) child->updateGContacts();
cdebug_tabw(535,-1);
}
void HVSlicingNode::clearGCells ()
{
for ( RHVSlicingNode* node : _slicingRouting ) node ->clearGCells();
for ( SlicingNode* child : _children ) child->clearGCells();
_gcell = NULL;
}
int HVSlicingNode::getNbDevices ()
{
int count = 0;
for ( SlicingNode* child : _children ) count += child->getNbDevices();
return count;
}
string HVSlicingNode::_getString () const
{
string s = Super::_getString();
s.insert( s.size()-1, " childs:" + getString(_children.size()) );
return s;
}
string HVSlicingNode::_getTypeName () const
{ return "HVSlicingNode"; }
void HVSlicingNode::setSymmetryFlag ( unsigned int flag )
{
SlicingNode::setSymmetryFlag( flag );
for ( RHVSlicingNode* node : _slicingRouting ) node ->setSymmetryFlag( flag );
for ( SlicingNode* child : _children ) child->setSymmetryFlag( flag );
}
void HVSlicingNode::setMaster ( SlicingNode* master )
{
_master = master;
if ( ((getType() == HorizontalSNode) and isHSymmetry())
or ((getType() == VerticalSNode ) and isVSymmetry()) ) {
for ( size_t i=0 ; i<_children.size() ; ++i )
_children[ _children.size()-1 - i ]->setMaster( master->getChild(i) );
} else {
for ( size_t i=0 ; i<_children.size() ; ++i )
_children[ i ]->setMaster( master->getChild(i) );
}
}
bool HVSlicingNode::isSymmetric ( SlicingNode* node, unsigned int symmetryType, unsigned int flags ) const
{
if ( (getType() == node->getType() )
and (getNbChild() == node->getNbChild() )
and (getToleranceBandH() == node->getToleranceBandH())
and (getToleranceBandW() == node->getToleranceBandW()) ) {
bool isSame = true;
if ( ((getType() == HorizontalSNode) and (symmetryType == HSymmetry))
or ((getType() == VerticalSNode ) and (symmetryType == VSymmetry)) ) {
size_t nbChilds = _children.size();
for ( size_t i=0 ; isSame and (i<nbChilds) ; ++i ) {
isSame = getChild(i)->isSymmetric( node->getChild(nbChilds-1-i), symmetryType );
}
} else {
size_t nbChilds = _children.size();
for ( size_t i=0 ; isSame and (i<nbChilds) ; ++i ) {
isSame = getChild(i)->isSymmetric( node->getChild(i), symmetryType );
}
}
if (not isSame and (flags & ShowDiff))
cerr << Warning( "HVSlicingNode::isSame() %s and %s differs (childs)."
, getString(this).c_str()
, getString(node).c_str() ) << endl;
return isSame;
}
if (flags & ShowDiff)
cerr << Warning( "HVSlicingNode::isSame() %s and %s differs."
, getString(this).c_str()
, getString(node).c_str() ) << endl;
return false;
}
bool HVSlicingNode::checkSymmetryNet ( unsigned int type, Net* net1, Net* net2 ) const
{
for ( const NetSymmetry& netSym : _netSymmetries ) {
if ( (get<1>(netSym) == net1)
and (get<2>(netSym) == net2)
and (get<0>(netSym) == type) )
return true;
}
return false;
}
void HVSlicingNode::addSymmetryNet ( unsigned int type, Net* net1, Net* net2 )
{
cerr << "HVSlicingNode::addSymmetryNet(): " << this << endl;
cerr << "* " << net1 << endl;
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
if (checkSymmetryNet(type,net1,net2)) {
cerr << Warning( "HVSlicingNode::addSymmetryNet(): Net symmetry already set." ) << endl;
return;
}
unsigned int ftype = type;
if (type == 1) ftype = NetRoutingState::Vertical;
else if (type == 2) ftype = NetRoutingState::Horizontal;
_netSymmetries.push_back( make_tuple(ftype,net1,net2) );
}
void HVSlicingNode::updateNetConstraints ()
{
if (not _cell) {
cerr << Warning( "HVSlicingNode::updateNetConstraints(): Cell not set." ) << endl;
return;
}
for ( NetSymmetry& netSym : _netSymmetries ) {
if (get<2>(netSym)) {
Net* masterNet = get<1>(netSym);
if (not masterNet)
cerr << Warning( "HVSlicingNode::updateNetConstraints() Reference Net not set." ) << endl;
else {
NetRoutingState* masterState = NetRoutingExtension::get( masterNet );
if (not masterState) masterState = NetRoutingExtension::create( masterNet );
masterState->setFlags ( NetRoutingState::AutomaticGlobalRoute
| NetRoutingState::Symmetric
| NetRoutingState::SymmetricMaster
| get<0>(netSym) );
Net* slaveNet = get<2>(netSym);
NetRoutingState* slaveState = NetRoutingExtension::get( slaveNet );
if (not slaveState) slaveState = NetRoutingExtension::create( slaveNet );
slaveState ->setFlags ( NetRoutingState::AutomaticGlobalRoute
| NetRoutingState::Symmetric
| get<0>((netSym)) );
slaveState ->setSymNet( masterNet );
masterState->setSymNet( slaveNet );
}
} else {
Net* net = get<1>(netSym);
if (not net)
cerr << Warning( "HVSlicingNode::updateNetConstraints() Single master Net not set." ) << endl;
else {
NetRoutingState* state = NetRoutingExtension::get( net );
if (not state) state = NetRoutingExtension::create( net );
state->setFlags( NetRoutingState::AutomaticGlobalRoute
| NetRoutingState::Symmetric
| get<0>(netSym) );
}
}
}
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
child->updateNetConstraints();
}
}
void HVSlicingNode::updateSymNetAxis ()
{
if (not _cell) {
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Cell not set." ) << endl;
return;
}
for ( const NetSymmetry& symNet : _netSymmetries ) {
if (_symmetries.empty())
throw Error( "HVSlicingNode::updateSymNetAxis(): \n"
" Symmetry request for \"%s\" in non-symmetrical node \"%s\"."
, getString(get<1>(symNet)->getName()).c_str()
, getString(this).c_str()
);
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
SlicingNode* n1 = getChild( _symmetries.front().first );
SlicingNode* n2 = getChild( _symmetries.front().second );
DbU::Unit xCenter = (n1->getX() + n2->getX() + n2->getWidth())/2;
DbU::Unit yCenter = (n1->getY() + n2->getY() + n2->getHeight())/2;
if (get<2>(symNet)) {
Net* masterNet = get<1>( symNet );
if (not masterNet)
cerr << Warning( "HVSlicingNode::updateSymNetAxis() Master net not set." ) << endl;
else {
NetRoutingState* masterState = NetRoutingExtension::get( masterNet );
if (not masterState)
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): UpdateNetConstraint need to be called first." ) << endl;
else {
if (get<0>(symNet) == NetRoutingState::Vertical ) masterState->setSymAxis( xCenter );
else if (get<0>(symNet) == NetRoutingState::Horizontal) masterState->setSymAxis( yCenter );
else
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." ) << endl;
Net* slaveNet = get<2>(symNet);
NetRoutingState* slaveState = NetRoutingExtension::get( slaveNet );
if (not slaveState)
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): updateSymNetAxis need to be called first." ) << endl;
else {
if (get<0>(symNet) == NetRoutingState::Vertical ) slaveState->setSymAxis( xCenter );
else if (get<0>(symNet) == NetRoutingState::Horizontal) slaveState->setSymAxis( yCenter );
else
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." ) << endl;
}
}
}
} else {
Net* net = get<1>(symNet);
if (not net)
cerr << Warning( "HVSlicingNode::updateSymNetAxis() Signle master net not set." ) << endl;
else {
NetRoutingState* state = NetRoutingExtension::get( net );
if (not state)
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): UpdateNetConstraint need to be called first." ) << endl;
else {
if (get<0>(symNet) == NetRoutingState::Vertical ) state->setSymAxis( xCenter );
else if (get<0>(symNet) == NetRoutingState::Horizontal) state->setSymAxis( yCenter );
else
cerr << Warning( "HVSlicingNode::updateSymNetAxis(): Unknown NetRoutingState type." ) << endl;
}
}
}
}
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
child->updateSymNetAxis();
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
}
}
void HVSlicingNode::flattenDigitalNets ()
{
if (not _cell) {
cerr << Warning( "HVSlicingNode::flattenDigitalNets(): Cell not set." ) << endl;
return;
}
for ( SlicingNode* child : _children ) {
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) ) {
child->flattenDigitalNets();
} else if (child->getType() == DeviceSNode) {
if ( child->getGCell()
and child->getInstance()
and child->getGCell()->isMatrix()) {
_cell->flattenNets( child->getInstance()
, Cell::Flags::BuildRings|Cell::Flags::WarnOnUnplacedInstances );
}
}
}
}
void HVSlicingNode::updateWireOccupation ( Anabatic::Dijkstra* dijkstra )
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
{
cdebug_log(535,1) << "HVSlicingNode::updateWireOccupation() on " << this << endl;
if (not _parent) {
for ( Anabatic::Vertex* vertex : dijkstra->getSources() ) {
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
cdebug_log(535,0) << "> " << vertex << endl;
Anabatic::GCell* gcell = vertex->getGCell();
SlicingNode* snode = findSlicingNode( gcell );
if (snode) {
cdebug_log(535,0) << "| isRouting():" << snode->isRouting() << endl;
if (snode->isRouting() and vertex->hasAData() )
snode->addWireOccupation( vertex->getIMin(), vertex->getIMax(), dijkstra->getNet() );
Analog integration part II. Analog place & route (slicing tree). * Change: In Hurricane::CellWidget, set the minimal size to 350 pixels to fit my normal DPI secondary screen... * Change: In Hurricane::Error(), reactivate the backtrace generation by default. Seriously slow down the program each time an Error is to be constructed. * Bug: In Analog::Device::preCreate(), check for NULL Technology before attempting to use it. * Change: In Hurricane/Analog, remove all '*Arguments*' classes and their Python interface. It was an obsoleted way of passing devices parameters to the Python layout generators (located in Oroshi). Now we just get them straight from the Device with the getParamter() method. * Change: In CRL::System CTOR, add Python pathes for Oroshi & Karakaze. * Change: In Oroshi/Python/WIP_*.py layout generator scripts, remove all uses of the "Arguments". Directly access the parameters through the device itself. Make the checkCoherency() with identical arguments as of layout(). * New: Bora tool that performs analog place & route. Based on a slicing tree representation. It is the thesis work of Eric Lao. Code beautyfication and some programming cleanup. * New: Karakaze tool, provide the Python base class AnalogDesign used to build an analog design. Create/configure devices and assemble them in a slicing tree. * Change: In Unicorn/cgt.py, display the stack trace in case of an ImportError exception as well as for other exceptions. Add Bora to the set for included tool engines.
2018-10-18 11:10:01 -05:00
}
}
}
cdebug_tabw(535,-1);
}
void HVSlicingNode::resetWireOccupation ()
{
for ( RHVSlicingNode* node : _slicingRouting ) node ->resetWireOccupation();
for ( SlicingNode* child : _children ) child->resetWireOccupation();
}
} // Bora namespace.