coriolis/bora/src/RVSlicingNode.cpp

195 lines
5.9 KiB
C++

// -*- 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 : "./RVSlicingNode.h" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/NetExternalComponents.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/AllianceFramework.h"
#include "bora/RVSlicingNode.h"
namespace Bora {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::DataBase;
using Hurricane::Box;
using Hurricane::NetExternalComponents;
// -------------------------------------------------------------------
// Class : "Bora::RVSlicingNode".
RVSlicingNode::RVSlicingNode ( DbU::Unit width )
: RHVSlicingNode()
{
RVBoxSet* node = RVBoxSet::create( width );
_nodeSets->push_back( node );
_boxSet = node;
_minWidth = width;
if (_parent) _minHeight = _parent->getHeight();
else _minHeight = 0;
DbU::Unit vpitch = _rg->getVerticalPitch();
if (width % vpitch)
cerr << Warning( "RVSlicingNode::RVSlicingNode(): On %s, width is not pitched (%s, pitch:%s)."
, getString(this).c_str()
, DbU::getValueString(width).c_str()
, DbU::getValueString(vpitch).c_str()
) << endl;
}
RVSlicingNode::RVSlicingNode ( Hurricane::Instance* instance )
: RHVSlicingNode()
{
RVBoxSet* node = RVBoxSet::create( instance->getMasterCell()->getAbutmentBox().getWidth() );
_nodeSets->push_back( node );
_boxSet = node;
_minHeight = instance->getMasterCell()->getAbutmentBox().getWidth();
setRailInstance( instance );
if (_parent) _minWidth = _parent->getWidth();
else _minWidth = 0;
}
RVSlicingNode::~RVSlicingNode ()
{ }
RVSlicingNode* RVSlicingNode::create ( DbU::Unit width )
{
return new RVSlicingNode( width );
}
RVSlicingNode* RVSlicingNode::create ( Hurricane::Net* net
, Hurricane::Layer* layer
, int npitch
, string cname
, string iname )
{
Cell* cell = Hurricane::Cell::create( Hurricane::DataBase::getDB()->getRootLibrary(), cname );
Net* subnet = Hurricane::Net::create( cell, net->getName() );
DbU::Unit width = CRL::AllianceFramework::get()->getRoutingGauge()->getVerticalPitch()* npitch;
subnet->setExternal( true );
Hurricane::Vertical* v = Hurricane::Vertical::create( subnet, layer, width/2, width );
NetExternalComponents::setExternal( v );
Hurricane::Instance* instance = Hurricane::Instance::create( _cell, iname, cell );
instance->getPlug( subnet )->setNet( net );
cell->setAbutmentBox( Box( 0, 0, width, 0) );
SlicingNode::addRailSegments( v );
return new RVSlicingNode( instance );
}
RVSlicingNode* RVSlicingNode::clone ( unsigned int tr )
{
RVSlicingNode* node = RVSlicingNode::create( getWidth() );
return node;
}
DbU::Unit RVSlicingNode::getHeight () const
{ return (_parent) ? _parent->getHeight() : 0; }
void RVSlicingNode::setWidth ( DbU::Unit width )
{ _boxSet->setWidth( width ); }
void RVSlicingNode::estimateChannelsSize ()
{
cdebug_log(535,0) << "RVSlicingNode::estimateChannelsSize() " << this << endl;
if (not getRailInstance()) {
if (_gcell and _rg) {
DbU::Unit vpitch = _rg->getVerticalPitch();
if (getMaxWireOccupation() > 0) {
int occupancyV = getMaxWireOccupation(); // +1 for having enough space
cdebug_log(535,0) << this << " has " << getMaxWireOccupation() << " (-1) tracks" << endl;
if (occupancyV % 2) ++occupancyV;
updateMasterSize( occupancyV * vpitch );
} else
updateMasterSize( 2 * vpitch );
setRoutingEstimated( RoutingEstimated );
} else
cerr << Error( "RHSlicingNode::estimateChannelsSize(: Technology missing." ) << endl;
}
}
void RVSlicingNode::_expandRoutingChannel ()
{
SlicingNode* master = this;
while ( master->getMaster() ) master = master->getMaster();
setWidth( master->getWidth() );
setRoutingEstimated( RoutingEstimated );
}
void RVSlicingNode::expandRoutingChannel ( DbU::Unit height, DbU::Unit width )
{
setWidth( width );
setRoutingEstimated( RoutingEstimated );
}
void RVSlicingNode::setGCell ( Anabatic::GCell* gcell )
{
cdebug_log(535,1) << "RVSlicingNode::setGCell() " << gcell << endl;
_gcell = gcell;
if (_gcell) {
if (_railInstance) _gcell->setType( Anabatic::Flags::VRailGCell );
else _gcell->setType( Anabatic::Flags::VChannelGCell );
}
cdebug_tabw(535,-1);
}
void RVSlicingNode::updateMasterSize ( DbU::Unit size )
{
SlicingNode* master = this;
while ( master->getMaster() ) master = master->getMaster();
if (master->getWidth() < size) master->setWidth( size );
}
void RVSlicingNode::setHeight( DbU::Unit height )
{
cerr << Error( "RVSlicingNode::setWidth(): Unimplemented on this type." ) << endl;
}
string RVSlicingNode::_getTypeName () const
{ return "RVSlicingNode"; }
} // Bora namespace.