Anabatic transient commit 13. Pre-load wires, imported from Katabatic.
This commit is contained in:
parent
eed9cc6f91
commit
3265c3ddcb
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -435,6 +435,7 @@ namespace Anabatic {
|
|||
{
|
||||
AnabaticEngine* engine = getForFramework( CreateEngine );
|
||||
engine->loadGlobalRouting( EngineLoadGrByNet );
|
||||
engine->layerAssign( EngineNoNetLayerAssign );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue