Anabatic transient commit 13. Pre-load wires, imported from Katabatic.

This commit is contained in:
Jean-Paul Chaput 2016-07-22 00:14:17 +02:00
parent eed9cc6f91
commit 3265c3ddcb
10 changed files with 1243 additions and 144 deletions

View File

@ -39,6 +39,7 @@ namespace Anabatic {
using Hurricane::Component;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::NetRoutingExtension;
using Hurricane::Cell;
using Hurricane::DebugSession;
using Hurricane::UpdateSession;
@ -82,21 +83,26 @@ namespace Anabatic {
AnabaticEngine::AnabaticEngine ( Cell* cell )
: Super(cell)
, _timer ()
, _configuration (new ConfigurationConcrete())
, _state (EngineCreation)
, _matrix ()
, _gcells ()
, _ovEdges ()
, _viewer (NULL)
, _flags (Flags::DestroyBaseContact)
, _stamp (-1)
, _densityMode (MaxDensity)
, _autoSegmentLut()
, _autoContactLut()
, _timer ()
, _configuration (new ConfigurationConcrete())
, _chipTools (cell)
, _state (EngineCreation)
, _matrix ()
, _gcells ()
, _ovEdges ()
, _viewer (NULL)
, _flags (Flags::DestroyBaseContact)
, _stamp (-1)
, _densityMode (MaxDensity)
, _autoSegmentLut ()
, _autoContactLut ()
, _netRoutingStates()
, _blockageNet (cell->getNet("blockagenet"))
{
_matrix.setCell( cell, _configuration->getSliceHeight() );
Edge::unity = _configuration->getSliceHeight();
if (not _blockageNet) _blockageNet = Net::create( cell, "blockagenet" );
}
@ -279,6 +285,34 @@ namespace Anabatic {
}
NetRoutingState* AnabaticEngine::getRoutingState ( Net* net, unsigned int flags )
{
NetRoutingState* state = NetRoutingExtension::get( net );
if (state) {
NetRoutingStates::iterator istate = _netRoutingStates.find( net->getId() );
if (istate != _netRoutingStates.end()) {
if (istate->second != state) {
cerr << Error( "AnabaticEngine::getRoutingStates() - %s incoherency between property and LUT:\n"
" Property:%x vs. LUT:%x, re-init LUT from property."
, getString(net->getName()).c_str()
, (void*)state
, (void*)(istate->second)) << endl;
_netRoutingStates.insert( make_pair(net->getId(), state) );
}
return state;
}
} else {
if (not (flags & Flags::Create)) return NULL;
state = NetRoutingExtension::create( net );
}
_netRoutingStates.insert( make_pair(net->getId(), state) );
return state;
}
void AnabaticEngine::cleanupGlobal ()
{
UpdateSession::open();
@ -561,6 +595,14 @@ namespace Anabatic {
{ for ( GCell* gcell : _gcells ) gcell->updateDensity(); }
size_t AnabaticEngine::checkGCellDensities ()
{
size_t saturateds = 0;
for ( GCell* gcell : _gcells ) saturateds += gcell->checkDensity();
return saturateds;
}
AutoSegment* AnabaticEngine::_lookup ( Segment* segment ) const
{
AutoSegmentLut::const_iterator it = _autoSegmentLut.find( segment );

View File

@ -30,6 +30,7 @@ endif ( CHECK_DETERMINISM )
anabatic/AutoHorizontal.h
anabatic/AutoVertical.h
anabatic/Session.h
anabatic/ChipTools.h
)
set( mocIncludes anabatic/GraphicAnabaticEngine.h )
set( pyIncludes anabatic/PyAnabaticEngine.h
@ -58,6 +59,9 @@ endif ( CHECK_DETERMINISM )
NetConstraints.cpp
NetOptimals.cpp
LoadGlobalRouting.cpp
ChipTools.cpp
LayerAssign.cpp
PreRouteds.cpp
)
set( pyCpps PyAnabaticEngine.cpp
PyGraphicAnabaticEngine.cpp

191
anabatic/src/ChipTools.cpp Normal file
View File

@ -0,0 +1,191 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./ChipTools.cpp" |
// +-----------------------------------------------------------------+
#include <string>
#include <sstream>
#include "hurricane/Warning.h"
#include "hurricane/Bug.h"
#include "hurricane/Torus.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/RoutingPad.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/AllianceFramework.h"
#include "anabatic/Session.h"
#include "anabatic/AutoContact.h"
#include "anabatic/AutoSegment.h"
#include "anabatic/AutoHorizontal.h"
#include "anabatic/AutoVertical.h"
#include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h"
namespace {
using namespace std;
using namespace CRL;
using namespace Hurricane;
using namespace Anabatic;
enum SegmentType { LocalSegments=0x10, GlobalSegments=0x20 };
bool isChip ( Cell* cell, Instance*& core, Cell*& referencePad )
{
AllianceFramework* af = AllianceFramework::get();
int pads = 0;
int cores = 0;
core = NULL;
referencePad = NULL;
forEach ( Instance*, iinstance, cell->getInstances() ) {
if ( af->isPad(iinstance->getMasterCell()) ) {
++pads;
if (not referencePad)
referencePad = iinstance->getMasterCell();
} else {
++cores;
core = *iinstance;
}
}
return (pads > 0) and (cores == 1);
}
void reselectPadRp ( Cell* cell )
{
AllianceFramework* af = AllianceFramework::get();
forEach ( Net*, inet, cell->getNets() ) {
if ( inet->getType() == Net::Type::GROUND ) continue;
if ( inet->getType() == Net::Type::POWER ) continue;
if ( inet->getType() == Net::Type::CLOCK ) continue;
forEach ( RoutingPad*, irp, inet->getRoutingPads() ) {
Instance* instance = irp->getOccurrence().getPath().getTailInstance();
if ( instance ) {
Cell* masterCell = instance->getMasterCell();
if ( af->isPad(masterCell) )
irp->setOnBestComponent(RoutingPad::LowestLayer);
}
} // RoutingPad*.
} // Net*.
}
} // End of anonymous namespace.
namespace Anabatic {
void AnabaticEngine::chipPrep ()
{
if (isChip()) {
reselectPadRp( getCell() );
}
}
ChipTools::ChipTools ( Cell* cell )
: _cell (cell)
, _core (NULL)
, _referencePad (NULL)
, _isChip (false)
, _chipBb (cell->getBoundingBox())
, _leftPadsBb ()
, _rightPadsBb ()
, _topPadsBb ()
, _bottomPadsBb ()
, _chipCorona ()
, _padWidth (0)
, _padHeight (0)
, _padPowerWidth(0)
, _padClockWidth(0)
{
_isChip = ::isChip( _cell, _core, _referencePad );
if (_isChip) {
_padHeight = _referencePad->getAbutmentBox().getHeight();
_padWidth = _referencePad->getAbutmentBox().getWidth();
Box outer = _cell->getBoundingBox().inflate ( -_padHeight );
_chipCorona = Torus ( outer, _core->getBoundingBox() );
_leftPadsBb = Box ( _chipBb.getXMin() , _chipBb.getYMin(), _chipCorona.getOuterBox().getXMin(), _chipBb.getYMax() );
_rightPadsBb = Box ( _chipCorona.getOuterBox().getXMax(), _chipBb.getYMin(), _chipBb.getXMax(), _chipBb.getYMax() );
_bottomPadsBb = Box ( _chipBb.getXMin() , _chipBb.getYMin(), _chipBb.getXMax(), _chipCorona.getOuterBox().getYMin() );
_topPadsBb = Box ( _chipBb.getXMin(), _chipCorona.getOuterBox().getYMax(), _chipBb.getXMax(), _chipBb.getYMax() );
Layer* metal3 = DataBase::getDB()->getTechnology()->getLayer( "METAL3" );
Net* net = _referencePad->getNet( "ck" );
forEach ( Horizontal*, ihorizontal, net->getHorizontals() ) {
if (ihorizontal->getLayer() == metal3) {
_padClockWidth = ihorizontal->getWidth();
break;
}
}
net = _referencePad->getNet( "vddi" );
forEach ( Horizontal*, ihorizontal, net->getHorizontals() ) {
if (ihorizontal->getLayer() == metal3) {
_padPowerWidth = ihorizontal->getWidth();
break;
}
}
cmess1 << " o Design is a complete chip." << endl;
cmess1 << " - Core: <" << _core->getName() << ">/<"
<< _core->getMasterCell()->getName() << ">." << endl;
cmess1 << " - Reference pad: <" << _referencePad->getName() << ">" << endl;
cmess1 << " - Corona: " << _chipCorona << "." << endl;
} else {
_chipCorona = Torus ( _cell->getBoundingBox(), _cell->getBoundingBox() );
}
}
string ChipTools::_getString () const
{
ostringstream s;
s << "<" << _getTypeName() << " " << _cell->getName()
<< " core:" << getString(((_core) ? _core->getName() : "NULL"))
<< ">";
return s.str();
}
Record* ChipTools::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add ( getSlot ( "_cell" , _cell ) );
record->add ( getSlot ( "_core" , _core ) );
record->add ( getSlot ( "_referencePad", _referencePad ) );
record->add ( getSlot ( "_isChip" , &_isChip ) );
record->add ( getSlot ( "_chipBb" , &_chipBb ) );
record->add ( getSlot ( "_leftPadsBb" , &_leftPadsBb ) );
record->add ( getSlot ( "_rightPadsBb" , &_rightPadsBb ) );
record->add ( getSlot ( "_topPadsBb" , &_topPadsBb ) );
record->add ( getSlot ( "_bottomPadsBb", &_bottomPadsBb ) );
record->add ( getSlot ( "_chipCorona" , &_chipCorona ) );
return record;
}
} // End of Anabatic namespace.

View File

@ -1588,8 +1588,8 @@ namespace Anabatic {
cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl;
// if (getAnabatic()->moveUpNetTrunk2(*isegment,globalNets,invalidateds))
// return true;
if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds))
return true;
}
return false;

View File

@ -133,13 +133,23 @@ namespace Anabatic {
stopMeasures();
printMeasures( "Anabatic Grid" );
Session::open( this );
setupSpecialNets();
setupPreRouteds ();
Session::close();
startMeasures();
cmess1 << " o Running global routing..." << endl;
NetSet netsToRoute;
for ( Net* net : cell->getNets() ) {
if (net->isSupply() or net->isClock()) continue;
NetRoutingState* state = getRoutingState( net );
if (state) {
if (state->isMixedPreRoute()) continue;
}
netsToRoute.insert( net );
}

View File

@ -435,6 +435,7 @@ namespace Anabatic {
{
AnabaticEngine* engine = getForFramework( CreateEngine );
engine->loadGlobalRouting( EngineLoadGrByNet );
engine->layerAssign( EngineNoNetLayerAssign );
}

View File

@ -0,0 +1,535 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./LayerAssign.cpp" |
// +-----------------------------------------------------------------+
#include <cstdlib>
#include <sstream>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/DebugSession.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/NetRoutingProperty.h"
#include "hurricane/Layer.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Pad.h"
#include "hurricane/Plug.h"
#include "hurricane/Instance.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Cell.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContact.h"
#include "anabatic/AutoSegment.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using Hurricane::DebugSession;
using Hurricane::ForEachIterator;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::NetRoutingExtension;
void AnabaticEngine::_desaturate ( unsigned int depth
, set<Net*>& globalNets
, unsigned long& total
, unsigned long& globals )
{
if (depth+2 > Session::getConfiguration()->getAllowedDepth()) {
cerr << Warning("Anabatic::_desaturate(): %s, no remaining upper layers."
,getString(Session::getRoutingGauge()->getRoutingLayer(depth)->getName()).c_str()
) << endl;
return;
}
cmess1 << " o Desaturate layer "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
GCellDensitySet queue ( depth, getGCells() );
GCell::Set invalidateds;
bool optimized = true;
while ( optimized ) {
Session::revalidate ();
optimized = false;
queue.requeue ();
std::set<GCell*,GCell::CompareByKey>::const_iterator igcell = queue.getGCells().begin();
size_t i = 0;
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
if (not (*igcell)->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;
for ( ; igcell!=queue.getGCells().end() ; ++igcell ) {
if ( (*igcell)->isSaturated( depth ) ) {
cparanoid << "[ERROR] Still saturated: @" << i << " " << *igcell << endl;
break;
}
}
break;
}
optimized = (*igcell)->stepNetDesaturate( depth, globalNets, invalidateds );
if ( optimized ) {
for ( GCell::Set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) {
queue.unqueue( *igcell );
}
break;
}
}
}
}
void AnabaticEngine::_layerAssignByLength ( Net* net, unsigned long& total, unsigned long& global, set<Net*>& globalNets )
{
DebugSession::open ( net, 140, 150 );
cdebug_log(149,0) << "Anabatic::_layerAssignByLength( " << net << " )" << endl;
cdebug_tabw(145,1);
bool isGlobal = false;
set<AutoContact*> globalContacts;
forEach ( Segment*, isegment, net->getSegments() ) {
total++;
if ( (*isegment)->getLength() > getGlobalThreshold() ) {
if (not isGlobal) {
isGlobal = true;
globalNets.insert( net );
}
global++;
if ((*isegment)->getLayer() == Session::getRoutingLayer(1)) (*isegment)->setLayer( Session::getRoutingLayer(3) );
if ((*isegment)->getLayer() == Session::getRoutingLayer(2)) (*isegment)->setLayer( Session::getRoutingLayer(4) );
}
}
cdebug_tabw(145,-1);
DebugSession::close();
}
void AnabaticEngine::_layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& globalNets )
{
cmess1 << " o Assign Layer (simple wirelength)." << endl;
forEach ( Net* , inet , getCell()->getNets() ) {
if (NetRoutingExtension::get(*inet)->isAutomaticGlobalRoute()) {
_layerAssignByLength ( *inet, total, global, globalNets );
}
} // forEach(Net*)
}
void AnabaticEngine::_layerAssignByTrunk ( Net* net, set<Net*>& globalNets, unsigned long& total, unsigned long& global )
{
DebugSession::open( net, 140, 150 );
cdebug_log(149,0) << "Anabatic::_layerAssignByTrunk ( " << net << " )" << endl;
cdebug_tabw(145,1);
bool isGlobal = false;
unsigned long netGlobal = 0;
unsigned long netTotal = 0;
set<AutoContact*> globalContacts;
forEach ( Segment*, isegment, net->getSegments() ) {
netTotal++;
if ((*isegment)->getLength() > getGlobalThreshold()) {
isGlobal = true;
netTotal = 0;
globalNets.insert( net );
break;
}
}
if (isGlobal) {
forEach ( Segment*, isegment, net->getSegments() ) {
netTotal++;
AutoSegment* autoSegment = Session::lookup( *isegment );
if ( autoSegment and not autoSegment->isStrongTerminal() ) {
netGlobal++;
cdebug_log(145,0) << "Migrate to M4/M5: " << autoSegment << endl;
if (autoSegment->isHorizontal()) autoSegment->setLayer( Session::getRoutingLayer(3) );
if (autoSegment->isVertical ()) autoSegment->setLayer( Session::getRoutingLayer(4) );
}
}
}
total += netTotal;
global += netGlobal;
cdebug_tabw(145,-1);
DebugSession::close();
}
void AnabaticEngine::_layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& globalNets )
{
cmess1 << " o Assign Layer (whole net trunk)." << endl;
forEach ( Net* , inet , getCell()->getNets() ) {
if (NetRoutingExtension::get(*inet)->isAutomaticGlobalRoute()) {
_layerAssignByTrunk( *inet, globalNets, total, global );
}
}
}
#if THIS_IS_DISABLED
void AnabaticEngine::moveULeft ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{
Net* net = seed->getNet();
DebugSession::open( net, 140, 150 );
cdebug_log(9000,0) << "Deter| Move left: " << seed << endl;
seed->moveULeft();
globalNets.insert( net );
GCell* begin = seed->getAutoSource()->getGCell();
GCell* end = seed->getAutoTarget()->getGCell();
if (seed->isHorizontal()) {
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() )
invalidateds.insert( gcell );
begin = begin->getDown();
end = end ->getDown();
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() )
invalidateds.insert( gcell );
} else {
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() )
invalidateds.insert( gcell );
begin = begin->getLeft();
end = end ->getLeft();
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() )
invalidateds.insert( gcell );
}
DebugSession::close();
}
void AnabaticEngine::moveURight ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{
Net* net = seed->getNet();
DebugSession::open( net, 140, 150 );
cdebug_log(9000,0) << "Deter| Move right: " << seed << endl;
seed->moveURight();
globalNets.insert( net );
GCell* begin = seed->getAutoSource()->getGCell();
GCell* end = seed->getAutoTarget()->getGCell();
if (seed->isHorizontal()) {
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() )
invalidateds.insert( gcell );
begin = begin->getUp();
end = end ->getUp();
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getRight() )
invalidateds.insert( gcell );
} else {
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() )
invalidateds.insert( gcell );
begin = begin->getRight();
end = end ->getRight();
for ( GCell* gcell=begin ; gcell and gcell!=end ; gcell=gcell->getUp() )
invalidateds.insert( gcell );
}
DebugSession::close();
}
#endif
bool AnabaticEngine::moveUpNetTrunk ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{
Net* net = seed->getNet();
unsigned int seedDepth = Session::getRoutingGauge()->getLayerDepth(seed->getLayer());
DebugSession::open( net, 140, 150 );
cdebug_log(9000,0) << "Deter| moveUpNetTrunk() depth:" << seedDepth << " " << seed << endl;
if (not seed->canMoveUp( 1.0, Flags::Propagate|Flags::AllowTerminal|Flags::NoCheckLayer) ) {
cdebug_log(9000,0) << "Deter| Reject seed move up, cannot move up." << endl;
DebugSession::close();
return false;
}
cdebug_tabw(149,1);
globalNets.insert( net );
vector< pair<AutoContact*,AutoSegment*> > stack;
vector<AutoSegment*> globals;
vector<AutoSegment*> locals;
stack.push_back( pair<AutoContact*,AutoSegment*>(NULL,seed) );
while ( not stack.empty() ) {
AutoContact* from = stack.back().first;
AutoSegment* segment = stack.back().second;
stack.pop_back();
if (segment->isLocal()) {
if (not segment->isStrongTerminal()) locals.push_back( segment );
continue;
}
if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
locals.push_back( segment );
continue;
}
// Do something here.
if (not segment->canMoveUp( 1.0
, Flags::Propagate
| Flags::AllowTerminal
| Flags::NoCheckLayer
| Flags::CheckLowDensity
) ) continue;
globals.push_back( segment );
AutoContact* source = segment->getAutoSource();
if (source != from) {
for ( AutoSegment* connected : source->getAutoSegments() ) {
if (connected != segment) { stack.push_back( make_pair(source,connected) ); }
}
}
AutoContact* target = segment->getAutoTarget();
if (target != from) {
for ( AutoSegment* connected : target->getAutoSegments() ) {
if (connected != segment) { stack.push_back( make_pair(target,connected) ); }
}
}
}
for ( size_t i=0 ; i<globals.size() ; ++i ) {
//cdebug_log(9000,0) << "Deter| Looking up G:" << globals[i] << endl;
unsigned int depth = Session::getRoutingGauge()->getLayerDepth( globals[i]->getLayer() );
globals[i]->changeDepth( depth+2, Flags::WithNeighbors );
vector<GCell*> gcells;
globals[i]->getGCells( gcells );
for ( size_t j=0 ; j<gcells.size() ; j++ ) {
invalidateds.insert( gcells[j] );
}
}
for ( size_t i=0 ; i<locals.size() ; ++i ) {
//cdebug_log(9000,0) << "Deter| Looking up L:" << locals[i] << endl;
unsigned int depth = Session::getRoutingGauge()->getLayerDepth(locals[i]->getLayer());
if (depth > seedDepth+1) continue;
if (locals[i]->canPivotUp(2.0,Flags::Propagate|Flags::NoCheckLayer)) {
locals[i]->changeDepth( depth+2, Flags::WithNeighbors );
//cdebug_log(9000,0) << "Deter| Trunk move up L:" << locals[i] << endl;
vector<GCell*> gcells;
locals[i]->getGCells( gcells );
for ( size_t j=0 ; j<gcells.size() ; j++ ) {
invalidateds.insert( gcells[j] );
}
}
}
cdebug_tabw(149,-1);
DebugSession::close();
return true;
}
#if THIS_IS_DISABLED
void AnabaticEngine::_balanceGlobalDensity ( unsigned int depth )
{
startMeasures();
Session::open( this );
cmess1 << " o Balance Global Density "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
GCellDensitySet queue ( depth, getGCells()) );
GCell::Set invalidateds;
bool optimized = true;
while ( optimized ) {
Session::revalidate();
optimized = false;
queue.requeue();
std::set<GCell*,GCell::CompareByKey>::const_iterator igcell = queue.getGCells().begin();
size_t i = 0;
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
cdebug_log(149,0) << "_balance: [" << depth << "]:"
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
if (not (*igcell)->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;
for ( ; igcell!=queue.getGCells().end() ; ++igcell ) {
if ((*igcell)->isSaturated(depth)) {
cparanoid << Error( "Still saturated: @%d %s", i, getString(*igcell).c_str() ) << endl;
break;
}
}
break;
}
optimized = (*igcell)->stepBalance( depth, invalidateds );
if (optimized) {
for ( GCell::Set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) {
queue.unqueue( *igcell );
}
break;
}
}
}
Session::close();
stopMeasures();
printMeasures( "balance" );
}
void AnabaticEngine::balanceGlobalDensity ()
{
cdebug_log(9000,0) << "Deter| Balance Global Density" << endl;
//_balanceGlobalDensity( 1 ); // metal2
//_balanceGlobalDensity( 2 ); // metal3
set<Net*> globalNets;
GCell::Set invalidateds;
Session::open( this );
vector<AutoSegment*> segments;
AutoSegmentLut::iterator ilut = _autoSegmentLut.begin();
for ( ; ilut!=_autoSegmentLut.end() ; ++ilut ) {
AutoSegment* segment = (*ilut).second;
if (segment->isLocal() or segment->isFixed()) continue;
if (not segment->isCanonical()) continue;
segments.push_back( segment );
}
// Sort on id before moving to ensure determinism.
sort( segments.begin(), segments.end(), AutoSegment::CompareId() );
for ( size_t i=0 ; i<segments.size() ; ++i ) {
// Hard-coded: reserve 3 tracks (1/20 * 3).
if (segments[i]->canMoveULeft(0.10)) {
moveULeft(segments[i],globalNets,invalidateds);
} else if (segments[i]->canMoveURight(0.10)) {
moveURight(segments[i],globalNets,invalidateds);
}
for ( GCell::Set::iterator igcell=invalidateds.begin() ; igcell!=invalidateds.end() ; ++igcell ) {
(*igcell)->updateDensity();
}
invalidateds.clear();
Session::revalidate();
}
Session::close();
}
#endif
void AnabaticEngine::layerAssign ( unsigned int method )
{
cdebug_log(9000,0) << "Deter| Layer Assignment" << endl;
set<Net*> globalNets;
unsigned long total = 0;
unsigned long global = 0;
startMeasures();
Session::open( this );
if (Session::getAllowedDepth() >= 3) {
switch ( method ) {
case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break;
case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break;
case EngineNoNetLayerAssign: break;
default:
stopMeasures();
Session::close();
throw Error( badMethod
, "Anabatic::layerAssign()"
, method
, getString(_cell).c_str()
);
}
globalNets.clear();
Session::revalidate();
if (getConfiguration()->getAllowedDepth() > 2) {
for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) {
_desaturate( depth, globalNets, total, global );
if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate();
}
globalNets.clear ();
Session::revalidate();
}
#if defined(CHECK_DATABASE)
_check( "after layer assignment" );
#endif
Session::setAnabaticFlags( Flags::WarnOnGCellOverload );
}
checkGCellDensities();
Session::close();
stopMeasures();
printMeasures( "assign" );
// cmess2 << " - Total segments : " << total << endl;
// cmess2 << " - Global segments : " << global << endl;
// cmess2 << " - Ratio : "
// << ((float)global/(float)total)*100.0 << "%." << endl;
}
} // Anabatic namespace.

173
anabatic/src/PreRouteds.cpp Normal file
View File

@ -0,0 +1,173 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2014-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PreRouteds.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/DeepNet.h"
#include "hurricane/Pin.h"
#include "hurricane/RoutingPad.h"
#include "crlcore/AllianceFramework.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::cerr;
using std::cout;
using std::endl;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::BasicLayer;
using Hurricane::RegularLayer;
using Hurricane::Component;
using Hurricane::Pin;
using Hurricane::DeepNet;
using Hurricane::Cell;
using Hurricane::NetRoutingExtension;
using CRL::RoutingGauge;
using CRL::RoutingLayerGauge;
using CRL::AllianceFramework;
void AnabaticEngine::setupSpecialNets ()
{
AllianceFramework* af = AllianceFramework::get();
for ( Net* net : _cell->getNets() ) {
const char* excludedType = NULL;
if (net->getType() == Net::Type::POWER ) excludedType = "POWER";
if (net->getType() == Net::Type::GROUND) excludedType = "GROUND";
if (excludedType) {
cparanoid << Warning( "%s is not a routable net (%s,excluded)."
, getString(net).c_str(), excludedType ) << endl;
}
if (af->isBLOCKAGE(net->getName())) excludedType = "BLOCKAGE";
if (excludedType) {
NetRoutingState* state = getRoutingState( net, Flags::Create );
state->setFlags( NetRoutingState::Fixed );
}
}
}
void AnabaticEngine::setupPreRouteds ()
{
cmess1 << " o Looking for fixed or manually global routed nets." << endl;
for ( Net* net : getCell()->getNets() ) {
if (net == _blockageNet) continue;
if (net->getType() == Net::Type::POWER ) continue;
if (net->getType() == Net::Type::GROUND) continue;
// Don't skip the clock.
vector<Segment*> segments;
vector<Contact*> contacts;
bool isPreRouted = false;
bool isFixed = false;
size_t rpCount = 0;
if (net->isDeepNet()) {
rpCount = 2;
Net* rootNet = dynamic_cast<Net*>(
dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
for( Component* component : rootNet->getComponents() ) {
if (dynamic_cast<Horizontal*>(component)) { isFixed = true; break; }
if (dynamic_cast<Vertical*> (component)) { isFixed = true; break; }
if (dynamic_cast<Contact*> (component)) { isFixed = true; break; }
}
} else {
for( Component* component : net->getComponents() ) {
if (dynamic_cast<Pin*>(component)) continue;
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage))
continue;
Horizontal* horizontal = dynamic_cast<Horizontal*>(component);
if (horizontal) {
segments.push_back( horizontal );
isPreRouted = true;
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
isFixed = true;
} else {
Vertical* vertical = dynamic_cast<Vertical*>(component);
if (vertical) {
isPreRouted = true;
segments.push_back( vertical );
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
isFixed = true;
} else {
Contact* contact = dynamic_cast<Contact*>(component);
if (contact) {
isPreRouted = true;
contacts.push_back( contact );
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
or (contact->getHeight() != Session::getViaWidth(contact->getLayer())) )
isFixed = true;
} else {
RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
if (rp) {
++rpCount;
} else {
// Plug* plug = dynamic_cast<Plug*>(component);
// if (plug) {
// cerr << "buildPreRouteds(): " << plug << endl;
// ++rpCount;
// }
}
}
}
}
}
}
if (isFixed or isPreRouted or (rpCount < 2)) {
NetRoutingState* state = getRoutingState( net, Flags::Create );
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
state->setFlags ( NetRoutingState::ManualGlobalRoute );
if (rpCount < 2)
state->setFlags ( NetRoutingState::Unconnected );
if (isFixed) {
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
state->setFlags ( NetRoutingState::Fixed );
} else {
if (rpCount > 1) {
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
for ( auto icontact : contacts ) {
AutoContact::createFrom( icontact );
}
for ( auto isegment : segments ) {
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( isegment->getSource() ));
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( isegment->getTarget() ));
AutoSegment* autoSegment = AutoSegment::create( source, target, isegment );
autoSegment->setFlags( SegUserDefined|SegAxisSet );
}
}
}
}
}
Session::revalidate();
}
} // Anabatic namespace.

View File

@ -22,10 +22,8 @@
#include <set>
#include "hurricane/Timer.h"
#include "hurricane/NetRoutingProperty.h"
namespace Hurricane {
class Name;
class Net;
class Cell;
class Instance;
class CellViewer;
}
@ -36,6 +34,7 @@ namespace Hurricane {
#include "anabatic/GCell.h"
#include "anabatic/AutoContact.h"
#include "anabatic/AutoSegments.h"
#include "anabatic/ChipTools.h"
namespace Anabatic {
@ -48,10 +47,12 @@ namespace Anabatic {
using Hurricane::Interval;
using Hurricane::Cell;
using Hurricane::CellViewer;
using Hurricane::NetRoutingState;
using CRL::ToolEngine;
typedef std::set<Net*,Entity::CompareById> NetSet;
typedef std::set<Net*,Entity::CompareById> NetSet;
typedef std::map<unsigned int,NetRoutingState*> NetRoutingStates;
class AnabaticEngine : public ToolEngine {
@ -67,138 +68,159 @@ namespace Anabatic {
public:
typedef ToolEngine Super;
public:
static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* );
static const Name& staticGetName ();
virtual const Name& getName () const;
virtual Configuration* getConfiguration ();
inline unsigned int getDensityMode () const;
inline CellViewer* getViewer () const;
inline void setViewer ( CellViewer* );
inline EngineState getState () const;
inline const Matrix* getMatrix () const;
inline const vector<GCell*>& getGCells () const;
inline const vector<Edge*>& getOvEdges () const;
inline GCell* getSouthWestGCell () const;
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getGCellUnder ( Point ) const;
int getCapacity ( Interval, Flags ) const;
size_t getNetsFromEdge ( const Edge*, NetSet& );
inline void setState ( EngineState state );
inline void setDensityMode ( unsigned int );
inline void addOv ( Edge* );
inline void removeOv ( Edge* );
// Dijkstra related functions.
inline int getStamp () const;
inline int incStamp ();
static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* );
static const Name& staticGetName ();
virtual const Name& getName () const;
virtual Configuration* getConfiguration ();
inline unsigned int getDensityMode () const;
inline CellViewer* getViewer () const;
inline void setViewer ( CellViewer* );
inline EngineState getState () const;
inline const Matrix* getMatrix () const;
inline const vector<GCell*>& getGCells () const;
inline const vector<Edge*>& getOvEdges () const;
inline GCell* getSouthWestGCell () const;
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getGCellUnder ( Point ) const;
int getCapacity ( Interval, Flags ) const;
size_t getNetsFromEdge ( const Edge*, NetSet& );
inline void setState ( EngineState state );
inline void setDensityMode ( unsigned int );
inline void addOv ( Edge* );
inline void removeOv ( Edge* );
// Dijkstra related functions.
inline int getStamp () const;
inline int incStamp ();
// Global routing related functions.
void globalRoute ();
void cleanupGlobal ();
void globalRoute ();
void cleanupGlobal ();
// Detailed routing related functions.
inline bool isInDemoMode () const;
inline bool doWarnOnGCellOverload () const;
inline bool doDestroyBaseContact () const;
inline bool doDestroyBaseSegment () const;
inline bool doDestroyTool () const;
inline DbU::Unit getGlobalThreshold () const;
inline float getSaturateRatio () const;
inline size_t getSaturateRp () const;
inline DbU::Unit getExtensionCap () const;
void updateDensity ();
inline void setGlobalThreshold ( DbU::Unit );
inline void setSaturateRatio ( float );
inline void setSaturateRp ( size_t );
void loadGlobalRouting ( unsigned int method );
void computeNetConstraints ( Net* );
void toOptimals ( Net* );
void updateNetTopology ( Net* );
void finalizeLayout ();
inline const AutoContactLut& _getAutoContactLut () const;
inline const AutoSegmentLut& _getAutoSegmentLut () const;
void _link ( AutoContact* );
void _link ( AutoSegment* );
void _unlink ( AutoContact* );
void _unlink ( AutoSegment* );
AutoContact* _lookup ( Contact* ) const;
AutoSegment* _lookup ( Segment* ) const;
void _loadGrByNet ();
void _loadNetGlobalRouting ( Net* );
void _computeNetOptimals ( Net* );
void _computeNetTerminals ( Net* );
void _alignate ( Net* );
void _saveNet ( Net* );
void _destroyAutoContacts ();
void _destroyAutoSegments ();
// Misc. functions.
inline const Flags& flags () const;
inline Flags& flags ();
void reset ();
void startMeasures ();
void stopMeasures ();
void printMeasures ( const string& ) const;
inline void _add ( GCell* );
inline void _remove ( GCell* );
inline void _updateLookup ( GCell* );
inline bool _inDestroy () const;
// Inspector support.
virtual Record* _getRecord () const;
virtual string _getString () const;
virtual string _getTypeName () const;
inline bool isInDemoMode () const;
inline bool isChip () const;
inline bool doWarnOnGCellOverload () const;
inline bool doDestroyBaseContact () const;
inline bool doDestroyBaseSegment () const;
inline bool doDestroyTool () const;
inline DbU::Unit getGlobalThreshold () const;
inline float getSaturateRatio () const;
inline size_t getSaturateRp () const;
inline DbU::Unit getExtensionCap () const;
inline Net* getBlockageNet () const;
inline const NetRoutingStates& getNetRoutingStates () const;
NetRoutingState* getRoutingState ( Net*, unsigned int flags=Flags::NoFlags );
void updateDensity ();
size_t checkGCellDensities ();
inline void setGlobalThreshold ( DbU::Unit );
inline void setSaturateRatio ( float );
inline void setSaturateRp ( size_t );
void chipPrep ();
void setupSpecialNets ();
void setupPreRouteds ();
void loadGlobalRouting ( unsigned int method );
void computeNetConstraints ( Net* );
void toOptimals ( Net* );
void updateNetTopology ( Net* );
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds );
void layerAssign ( unsigned int method );
void finalizeLayout ();
inline const AutoContactLut& _getAutoContactLut () const;
inline const AutoSegmentLut& _getAutoSegmentLut () const;
void _link ( AutoContact* );
void _link ( AutoSegment* );
void _unlink ( AutoContact* );
void _unlink ( AutoSegment* );
AutoContact* _lookup ( Contact* ) const;
AutoSegment* _lookup ( Segment* ) const;
void _loadGrByNet ();
void _loadNetGlobalRouting ( Net* );
void _computeNetOptimals ( Net* );
void _computeNetTerminals ( Net* );
void _alignate ( Net* );
void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals );
void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
void _saveNet ( Net* );
void _destroyAutoContacts ();
void _destroyAutoSegments ();
// Misc. functions.
inline const Flags& flags () const;
inline Flags& flags ();
void reset ();
void startMeasures ();
void stopMeasures ();
void printMeasures ( const string& ) const;
inline void _add ( GCell* );
inline void _remove ( GCell* );
inline void _updateLookup ( GCell* );
inline bool _inDestroy () const;
// Inspector support.
virtual Record* _getRecord () const;
virtual string _getString () const;
virtual string _getTypeName () const;
protected:
AnabaticEngine ( Cell* );
virtual ~AnabaticEngine ();
virtual void _postCreate ();
virtual void _preDestroy ();
void _gutAnabatic ();
private:
AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& );
AnabaticEngine ( Cell* );
virtual ~AnabaticEngine ();
virtual void _postCreate ();
virtual void _preDestroy ();
void _gutAnabatic ();
private:
AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& );
private:
static Name _toolName;
Timer _timer;
Configuration* _configuration;
EngineState _state;
Matrix _matrix;
vector<GCell*> _gcells;
vector<Edge*> _ovEdges;
CellViewer* _viewer;
Flags _flags;
int _stamp;
unsigned int _densityMode;
AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut;
static Name _toolName;
Timer _timer;
Configuration* _configuration;
ChipTools _chipTools;
EngineState _state;
Matrix _matrix;
vector<GCell*> _gcells;
vector<Edge*> _ovEdges;
CellViewer* _viewer;
Flags _flags;
int _stamp;
unsigned int _densityMode;
AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut;
NetRoutingStates _netRoutingStates;
Net* _blockageNet;
};
inline EngineState AnabaticEngine::getState () const { return _state; }
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
inline unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; }
inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
inline const Flags& AnabaticEngine::flags () const { return _flags; }
inline Flags& AnabaticEngine::flags () { return _flags; }
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline EngineState AnabaticEngine::getState () const { return _state; }
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
inline unsigned int AnabaticEngine::getDensityMode () const { return _densityMode; }
inline void AnabaticEngine::setDensityMode ( unsigned int mode ) { _densityMode=mode; }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
inline const Flags& AnabaticEngine::flags () const { return _flags; }
inline Flags& AnabaticEngine::flags () { return _flags; }
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline const NetRoutingStates& AnabaticEngine::getNetRoutingStates () const { return _netRoutingStates; }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline void AnabaticEngine::_add ( GCell* gcell )
{
@ -227,6 +249,9 @@ namespace Anabatic {
if (*iedge == edge) { _ovEdges.erase(iedge); break; }
}
extern const char* badMethod;
} // Anabatic namespace.

View File

@ -0,0 +1,118 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2016, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/ChipTools.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_CHIP_TOOLS_H
#define ANABATIC_CHIP_TOOLS_H
#include <string>
#include "hurricane/DbU.h"
#include "hurricane/Torus.h"
namespace Hurricane {
class Cell;
class Instance;
}
namespace Anabatic {
using Hurricane::Record;
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Torus;
using Hurricane::Cell;
using Hurricane::Instance;
class ChipTools {
public:
ChipTools ( Cell* );
inline bool isChip () const;
inline Cell* getCell () const;
inline Instance* getCore () const;
inline Cell* getReferencePad () const;
inline DbU::Unit getPadWidth () const;
inline DbU::Unit getPadHeight () const;
inline DbU::Unit getPadPowerWidth () const;
inline DbU::Unit getPadClockWidth () const;
inline const Box& getChipBb () const;
inline const Box& getLeftPadsBb () const;
inline const Box& getRightPadsBb () const;
inline const Box& getTopPadsBb () const;
inline const Box& getBottomPadsBb () const;
inline const Torus& getCorona () const;
inline const Box& getCoronaBb () const;
inline bool intersectVPads ( const Box& ) const;
inline bool intersectHPads ( const Box& ) const;
inline bool vPadsEnclosed ( const Box& ) const;
inline bool hPadsEnclosed ( const Box& ) const;
public:
Record* _getRecord () const;
std::string _getString () const;
inline std::string _getTypeName () const;
private:
Cell* _cell;
Instance* _core;
Cell* _referencePad;
bool _isChip;
Box _chipBb;
Box _leftPadsBb;
Box _rightPadsBb;
Box _topPadsBb;
Box _bottomPadsBb;
Torus _chipCorona;
DbU::Unit _padWidth;
DbU::Unit _padHeight;
DbU::Unit _padPowerWidth;
DbU::Unit _padClockWidth;
};
// Inline Functions.
inline bool ChipTools::isChip () const { return _isChip; }
inline Cell* ChipTools::getCell () const { return _cell; }
inline Instance* ChipTools::getCore () const { return _core; }
inline Cell* ChipTools::getReferencePad () const { return _referencePad; }
inline DbU::Unit ChipTools::getPadWidth () const { return _padWidth; }
inline DbU::Unit ChipTools::getPadHeight () const { return _padHeight; }
inline DbU::Unit ChipTools::getPadPowerWidth () const { return _padPowerWidth; }
inline DbU::Unit ChipTools::getPadClockWidth () const { return _padClockWidth; }
inline const Box& ChipTools::getChipBb () const { return _chipBb; }
inline const Box& ChipTools::getLeftPadsBb () const { return _leftPadsBb; };
inline const Box& ChipTools::getRightPadsBb () const { return _rightPadsBb; };
inline const Box& ChipTools::getTopPadsBb () const { return _topPadsBb; };
inline const Box& ChipTools::getBottomPadsBb () const { return _bottomPadsBb; };
inline const Torus& ChipTools::getCorona () const { return _chipCorona; };
inline const Box& ChipTools::getCoronaBb () const { return _chipCorona.getOuterBox(); }
inline std::string ChipTools::_getTypeName () const { return "ChipTools"; }
inline bool ChipTools::intersectVPads ( const Box& box ) const
{ return _leftPadsBb.intersect(box) or _rightPadsBb.intersect(box); }
inline bool ChipTools::intersectHPads ( const Box& box ) const
{ return _topPadsBb.intersect(box) or _bottomPadsBb.intersect(box); }
inline bool ChipTools::vPadsEnclosed ( const Box& box ) const
{ return _leftPadsBb.contains(box) or _rightPadsBb.contains(box); }
inline bool ChipTools::hPadsEnclosed ( const Box& box ) const
{ return _topPadsBb.contains(box) or _bottomPadsBb.contains(box); }
} // Anabatic namespace.
INSPECTOR_PV_SUPPORT(Anabatic::ChipTools);
#endif // ANABATIC_CHIP_TOOLS_H