* ./katabatic:

- New: In GCell & LayerAssign, adds a supplemental desaturation steps when
        a GCell containts too many (more than 7) RoutingPads in M1. This is
        especially useful for the eFPGA matrix with it's custom made cells.
This commit is contained in:
Jean-Paul Chaput 2010-04-12 11:22:11 +00:00
parent fe7acbc389
commit 3069af8a63
4 changed files with 94 additions and 5 deletions

View File

@ -34,6 +34,7 @@
#include "hurricane/Layer.h" #include "hurricane/Layer.h"
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/RoutingPad.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "katabatic/AutoContact.h" #include "katabatic/AutoContact.h"
#include "katabatic/AutoSegment.h" #include "katabatic/AutoSegment.h"
@ -304,6 +305,18 @@ namespace Katabatic {
} }
size_t GCell::getRoutingPads ( set<RoutingPad*>& rps )
{
for ( size_t i=0 ; i<_contacts.size() ; ++i ) {
RoutingPad* rp = dynamic_cast<RoutingPad*>(_contacts[i]->getAnchor());
if ( rp ) {
rps.insert ( rp );
}
}
return rps.size();
}
float GCell::getHCapacity () const float GCell::getHCapacity () const
{ {
return (float)( _box.getHeight() / DbU::lambda(5.0) + 1 ); return (float)( _box.getHeight() / DbU::lambda(5.0) + 1 );
@ -684,6 +697,42 @@ namespace Katabatic {
} }
void GCell::rpDesaturate ( set<Net*>& globalNets )
{
set<RoutingPad*> rps;
getRoutingPads ( rps );
set<Net*> rpNets;
set<RoutingPad*>::iterator irp = rps.begin();
for ( ; irp != rps.end() ; ++irp ) {
if ( (*irp)->getLayer() != Session::getRoutingLayer(0) ) continue;
rpNets.insert ( (*irp)->getNet() );
}
if ( rpNets.size() < 8 ) return;
cerr << "[WARNING] " << this << " has " << rps.size() << " terminals h:"
<< _hsegments.size() << endl;
irp = rps.begin();
for ( ; irp != rps.end() ; ++irp )
cerr << " " << *irp << endl;
AutoSegment* segment;
while ( stepDesaturate ( 1, globalNets, segment, true ) ) {
//cerr << "Moved up: " << segment << endl;
}
#if 0
set<RoutingPad*>::iterator ipad = rps.begin();
for ( ; ipad != rps.end() ; ++ipad ) {
forEach ( Segment*, isegment, (*ipad)->getSlaveComponents().getSubSet<Segment*>() ) {
}
}
#endif
}
bool GCell::hasFreeTrack ( size_t depth ) const bool GCell::hasFreeTrack ( size_t depth ) const
{ {
if (_invalid) const_cast<GCell*>(this)->updateDensity(); if (_invalid) const_cast<GCell*>(this)->updateDensity();
@ -732,7 +781,7 @@ namespace Katabatic {
} }
bool GCell::stepDesaturate ( unsigned int depth, set<Net*>& globalNets, AutoSegment*& moved ) bool GCell::stepDesaturate ( unsigned int depth, set<Net*>& globalNets, AutoSegment*& moved, bool force )
{ {
#if defined(CHECK_DETERMINISM) #if defined(CHECK_DETERMINISM)
cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl; cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl;
@ -743,7 +792,7 @@ namespace Katabatic {
//float density = _densities[depth]; //float density = _densities[depth];
//float densityUp = _densities[depth+2]; //float densityUp = _densities[depth+2];
if ( !isSaturated(depth) ) return false; if ( not force and not isSaturated(depth) ) return false;
float capacity; float capacity;
vector<AutoSegment*>::iterator isegment; vector<AutoSegment*>::iterator isegment;

View File

@ -256,7 +256,7 @@ namespace Katabatic {
switch ( method ) { switch ( method ) {
case LayerAssignByLength: _layerAssignByLength(total,global,globalNets); break; case LayerAssignByLength: _layerAssignByLength(total,global,globalNets); break;
case LayerAssignByTrunk: _layerAssignByTrunk (total,global,globalNets); break; case LayerAssignByTrunk: _layerAssignByTrunk (total,global,globalNets); break;
case NoNetLayerAssign: break; case NoNetLayerAssign: break;
default: default:
stopMeasures (); stopMeasures ();
@ -294,6 +294,20 @@ namespace Katabatic {
_print ( _routingNets[i] ); _print ( _routingNets[i] );
#endif #endif
// Look for RoutingPad overload.
vector<GCell*> gcells = *(_gcellGrid->getGCellVector());
for ( size_t i=0 ; i<gcells.size() ; ++i ) {
gcells[i]->rpDesaturate ( globalNets );
// set<RoutingPad*> rps;
// gcells[i]->getRoutingPads ( rps );
// if ( rps.size() > 7 ) {
// cerr << "[WARNING] " << gcells[i] << "has " << rps.size() << " terminals." << endl;
// }
}
Session::revalidate ();
Session::setWarnGCellOverload ( true ); Session::setWarnGCellOverload ( true );
_gcellGrid->checkDensity (); _gcellGrid->checkDensity ();

View File

@ -1988,16 +1988,38 @@ namespace {
AutoContact* localContact = (_south) ? _southWestContact : _northEastContact; AutoContact* localContact = (_south) ? _southWestContact : _northEastContact;
//localContact->setHAlignate ( true ); //localContact->setHAlignate ( true );
bool doTurn = (_topology & GLOBAL_SPLIT) and (_routingPads.size() == 1);
for ( unsigned int i = 0 ; i < _routingPads.size() ; i++ ) { for ( unsigned int i = 0 ; i < _routingPads.size() ; i++ ) {
AutoContact* rpContact = _GCell_rp_Access ( _gcell, _routingPads[i], true, false ); AutoContact* rpContact = _GCell_rp_Access ( _gcell, _routingPads[i], true, false );
AutoContact* turn1
= (doTurn) ? AutoContact::create(_gcell,_net,Session::getContactLayer(1)) : localContact;
segment = AutoSegment::create ( rpContact segment = AutoSegment::create ( rpContact
, localContact , turn1
, Constant::Horizontal , Constant::Horizontal
, AutoSegment::Local , AutoSegment::Local
, true , true
, false ); , false );
setIsRoutingPadSmall ( _routingPads[i], hsmall, vsmall, punctual ); setIsRoutingPadSmall ( _routingPads[i], hsmall, vsmall, punctual );
if ( not vsmall ) segment->setStrap ( true ); if ( not vsmall ) segment->setStrap ( true );
if ( doTurn ) {
AutoContact* turn2 = AutoContact::create ( _gcell, _net, Session::getContactLayer(1) );
segment = AutoSegment::create ( turn1
, turn2
, Constant::Vertical
, AutoSegment::Local
, true
, false );
segment->setStrap ( true );
segment = AutoSegment::create ( turn2
, localContact
, Constant::Horizontal
, AutoSegment::Local
, true
, false );
segment->setStrap ( true );
}
} }
if ( _topology & (GLOBAL_VERTICAL|GLOBAL_FORK) ) { if ( _topology & (GLOBAL_VERTICAL|GLOBAL_FORK) ) {

View File

@ -38,6 +38,7 @@
#include "hurricane/ExtensionGo.h" #include "hurricane/ExtensionGo.h"
namespace Hurricane { namespace Hurricane {
class Name; class Name;
class RoutingPad;
} }
#include "crlcore/RoutingLayerGauge.h" #include "crlcore/RoutingLayerGauge.h"
@ -59,6 +60,7 @@ namespace Katabatic {
using Hurricane::Box; using Hurricane::Box;
using Hurricane::Interval; using Hurricane::Interval;
using Hurricane::ExtensionGo; using Hurricane::ExtensionGo;
using Hurricane::RoutingPad;
class GCellGrid; class GCellGrid;
class AutoContact; class AutoContact;
@ -145,6 +147,7 @@ namespace Katabatic {
AutoSegments getVStopSegments (); AutoSegments getVStopSegments ();
inline AutoSegments getStartSegments ( unsigned int direction ); inline AutoSegments getStartSegments ( unsigned int direction );
inline AutoSegments getStopSegments ( unsigned int direction ); inline AutoSegments getStopSegments ( unsigned int direction );
size_t getRoutingPads ( set<RoutingPad*>& );
inline const Key& getKey () const; inline const Key& getKey () const;
size_t checkDensity () const; size_t checkDensity () const;
bool checkEdgeSaturation ( float threshold ) const; bool checkEdgeSaturation ( float threshold ) const;
@ -162,7 +165,8 @@ namespace Katabatic {
size_t updateDensity (); size_t updateDensity ();
inline void updateKey ( unsigned int depth ); inline void updateKey ( unsigned int depth );
void desaturate ( unsigned int depth, set<Net*>& ); void desaturate ( unsigned int depth, set<Net*>& );
bool stepDesaturate ( unsigned int depth, set<Net*>&, AutoSegment*& moved ); bool stepDesaturate ( unsigned int depth, set<Net*>&, AutoSegment*& moved, bool force=false );
void rpDesaturate ( set<Net*>& );
inline void invalidate (); inline void invalidate ();
// Inspector Management. // Inspector Management.
Record* _getRecord () const; Record* _getRecord () const;