2010-03-09 09:24:29 -06:00
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
2016-03-06 05:36:18 -06:00
|
|
|
// Copyright (c) UPMC 2008-2016, All Rights Reserved
|
2010-03-09 09:24:29 -06:00
|
|
|
//
|
2013-12-03 18:58:58 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:29 -06:00
|
|
|
// | C O R I O L I S |
|
|
|
|
// | K a t a b a t i c - Routing Toolbox |
|
|
|
|
// | |
|
|
|
|
// | Author : Jean-Paul CHAPUT |
|
2013-12-03 18:58:58 -06:00
|
|
|
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
2010-03-09 09:24:29 -06:00
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./GCellGrid.cpp" |
|
2013-12-03 18:58:58 -06:00
|
|
|
// +-----------------------------------------------------------------+
|
2010-03-09 09:24:29 -06:00
|
|
|
|
|
|
|
|
|
|
|
#include "hurricane/Error.h"
|
|
|
|
#include "hurricane/Cell.h"
|
|
|
|
#include "knik/KnikEngine.h"
|
|
|
|
#include "katabatic/Session.h"
|
|
|
|
#include "katabatic/GCellGrid.h"
|
|
|
|
#include "katabatic/KatabaticEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Katabatic {
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using Hurricane::tab;
|
|
|
|
using Hurricane::Error;
|
|
|
|
using Hurricane::ForEachIterator;
|
|
|
|
using Knik::KnikEngine;
|
|
|
|
|
|
|
|
|
|
|
|
const char* missingKnikEngine =
|
|
|
|
"%s :\n\n"
|
|
|
|
" Hey, Banana! You forgot to run the Knik global router on %s.\n";
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
// Class : "Katabatic::GCellGrid".
|
|
|
|
|
|
|
|
|
|
|
|
GCellGrid::GCellGrid ( KatabaticEngine* ktbt )
|
2010-08-22 07:37:48 -05:00
|
|
|
: Grid<GCell> (ktbt->getCell()->getAbutmentBox())
|
|
|
|
, _katabatic (ktbt)
|
2010-12-12 15:43:25 -06:00
|
|
|
, _densityMode (MaxDensity)
|
2010-08-22 07:37:48 -05:00
|
|
|
, _hEdgeCapacity(ktbt->getConfiguration()->getHEdgeCapacity())
|
|
|
|
, _vEdgeCapacity(ktbt->getConfiguration()->getVEdgeCapacity())
|
2010-03-09 09:24:29 -06:00
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
void GCellGrid::_postCreate ()
|
|
|
|
{
|
2014-03-15 04:47:37 -05:00
|
|
|
KnikEngine* knik;
|
2010-03-09 09:24:29 -06:00
|
|
|
knik = KnikEngine::get ( getCell() );
|
|
|
|
if ( !knik )
|
|
|
|
throw Error ( missingKnikEngine, "GCellGrid::_postCreate()", getString(getCell()).c_str() );
|
|
|
|
|
|
|
|
vector<DbU::Unit> knikGraduations;
|
|
|
|
|
|
|
|
knik->getHorizontalCutLines ( knikGraduations );
|
|
|
|
for ( size_t i=0 ; i<knikGraduations.size() ; i++ )
|
|
|
|
_yGraduations.addGraduation ( knikGraduations[i] );
|
|
|
|
_yGraduations.sort ();
|
|
|
|
_rows = _yGraduations.getSize() - 1;
|
|
|
|
|
|
|
|
knik->getVerticalCutLines ( knikGraduations );
|
|
|
|
for ( size_t i=0 ; i<knikGraduations.size() ; i++ )
|
|
|
|
_xGraduations.addGraduation ( knikGraduations[i] );
|
|
|
|
_xGraduations.sort ();
|
|
|
|
_columns = _xGraduations.getSize() - 1;
|
|
|
|
|
|
|
|
_rawSize = _columns * _rows;
|
|
|
|
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_log(145,1) << "Katabatic GCell Matrix [" << getColumns() << "x" << getRows() << "]" << endl;
|
|
|
|
cdebug_log(145,0) << "_xGraduations := " << _xGraduations._print() << endl;
|
|
|
|
cdebug_log(145,0) << "_yGraduations := " << _yGraduations._print() << endl;
|
2010-03-09 09:24:29 -06:00
|
|
|
|
|
|
|
for ( unsigned int row=0 ; row < getRows() ; row++ ) {
|
|
|
|
for ( unsigned int column=0; column<getColumns() ; column++ ) {
|
|
|
|
Box boundingBox = Box ( _xGraduations[column ]
|
|
|
|
, _yGraduations[row ]
|
|
|
|
, _xGraduations[column+1]
|
|
|
|
, _yGraduations[row +1]
|
|
|
|
);
|
|
|
|
|
|
|
|
_gcells.push_back ( GCell::create ( this, _gcells.size(), boundingBox ) );
|
|
|
|
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_log(145,0) << "GCell [" << column << "," << row << "] "
|
2010-03-09 09:24:29 -06:00
|
|
|
<< _gcells[_gcells.size()-1] << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cmess1 << " o Reading GCell grid from Knik ["
|
2010-05-03 04:16:28 -05:00
|
|
|
<< getColumns() << "x" << getRows() << "] "
|
|
|
|
<< "(" << (getColumns()*getRows()) << ")." << endl;
|
2010-03-09 09:24:29 -06:00
|
|
|
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_tabw(145,-1);
|
2010-03-09 09:24:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GCellGrid* GCellGrid::create ( KatabaticEngine* ktbt )
|
|
|
|
{
|
|
|
|
GCellGrid* grid = new GCellGrid ( ktbt );
|
|
|
|
grid->_postCreate ();
|
|
|
|
return grid;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GCellGrid::~GCellGrid ()
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
|
|
void GCellGrid::_preDestroy ()
|
|
|
|
{
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_log(145,1) << "GCellGrid::_preDestroy()" << endl;
|
2010-03-09 09:24:29 -06:00
|
|
|
|
|
|
|
vector<GCell*>::iterator it = _gcells.begin();
|
|
|
|
vector<GCell*>::iterator end = _gcells.end ();
|
|
|
|
for ( ; it != end ; it++ ) (*it)->destroy ();
|
|
|
|
|
2016-06-11 14:56:12 -05:00
|
|
|
cdebug_tabw(145,-1);
|
2010-03-09 09:24:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Cell* GCellGrid::getCell () const
|
|
|
|
{
|
|
|
|
return _katabatic->getCell();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-04-23 08:13:54 -05:00
|
|
|
Interval GCellGrid::getUSide ( unsigned int direction ) const
|
|
|
|
{
|
|
|
|
Interval side;
|
|
|
|
switch ( direction ) {
|
|
|
|
default:
|
2016-04-13 11:42:55 -05:00
|
|
|
cerr << Error( "GCellGrid::getUSide(): Unknown direction flag \"%i\""
|
|
|
|
, direction ) << endl;
|
|
|
|
case KbHorizontal: side = Interval(_boundingBox.getXMin(),_boundingBox.getXMax()); break;
|
|
|
|
case KbVertical: side = Interval(_boundingBox.getYMin(),_boundingBox.getYMax()); break;
|
2010-04-23 08:13:54 -05:00
|
|
|
}
|
|
|
|
return side;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-12-03 18:58:58 -06:00
|
|
|
void GCellGrid::updateContacts ( unsigned int flags )
|
2010-03-09 09:24:29 -06:00
|
|
|
{
|
2013-12-03 18:58:58 -06:00
|
|
|
if (flags & KbOpenSession) Session::open( _katabatic );
|
2010-03-09 09:24:29 -06:00
|
|
|
|
|
|
|
forEach ( GCell*, gcell, getGCells() )
|
2013-12-03 18:58:58 -06:00
|
|
|
gcell->updateContacts();
|
2010-03-09 09:24:29 -06:00
|
|
|
|
2013-12-03 18:58:58 -06:00
|
|
|
if (flags & KbOpenSession) Session::close();
|
2010-03-09 09:24:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t GCellGrid::updateDensity ()
|
|
|
|
{
|
|
|
|
size_t saturateds = 0;
|
|
|
|
forEach ( GCell*, gcell, getGCells() ) {
|
|
|
|
saturateds += gcell->updateDensity ();
|
|
|
|
}
|
|
|
|
return saturateds;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t GCellGrid::checkDensity () const
|
|
|
|
{
|
|
|
|
size_t saturateds = 0;
|
|
|
|
forEach ( GCell*, gcell, const_cast<GCellGrid*>(this)->getGCells() ) {
|
|
|
|
saturateds += gcell->checkDensity ();
|
|
|
|
}
|
|
|
|
return saturateds;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Express "xEdgeCapacity" ratio as "xTracksReservedLocal" a number of tracks.
* Change: In Kite, Katabatic & Knik, express the number of tracks truly
available to the global router by the number of tracks reserved to
the local routage inside a GCell. Replace the ratio parameter
"hEdgeCapacity" by an integer parameter "hTracksReservedLocal"
(duplicate for verticals).
It is more explicit to give directly the number of tracks that
are to be used locally, and potentially saves us from rouding
problems when calculating the number of availables tracks.
Note: we cannot do that for the layer saturateRatio as it
uses the density ratio that take account local wires, leading
to fractional results.
* Change: In Katabatic, in <GCellGrid>, rename checkEdgeSaturation()
into checkEdgeOverflow(), more explicit.
* Change: In Knik, in <Graph>, display the computed capacities of the
lower left node edges (should be the same througout all the grid).
* Change: In Unicorn, in <cgt.py>, uses the new parameters names for
edge density.
2014-06-10 09:58:52 -05:00
|
|
|
bool GCellGrid::checkEdgeOverflow ( size_t hreserved, size_t vreserved) const
|
2010-03-09 09:24:29 -06:00
|
|
|
{
|
|
|
|
bool overload = false;
|
|
|
|
forEach ( GCell*, gcell, const_cast<GCellGrid*>(this)->getGCells() ) {
|
Express "xEdgeCapacity" ratio as "xTracksReservedLocal" a number of tracks.
* Change: In Kite, Katabatic & Knik, express the number of tracks truly
available to the global router by the number of tracks reserved to
the local routage inside a GCell. Replace the ratio parameter
"hEdgeCapacity" by an integer parameter "hTracksReservedLocal"
(duplicate for verticals).
It is more explicit to give directly the number of tracks that
are to be used locally, and potentially saves us from rouding
problems when calculating the number of availables tracks.
Note: we cannot do that for the layer saturateRatio as it
uses the density ratio that take account local wires, leading
to fractional results.
* Change: In Katabatic, in <GCellGrid>, rename checkEdgeSaturation()
into checkEdgeOverflow(), more explicit.
* Change: In Knik, in <Graph>, display the computed capacities of the
lower left node edges (should be the same througout all the grid).
* Change: In Unicorn, in <cgt.py>, uses the new parameters names for
edge density.
2014-06-10 09:58:52 -05:00
|
|
|
overload = gcell->checkEdgeSaturation(hreserved,vreserved) or overload;
|
2010-03-09 09:24:29 -06:00
|
|
|
}
|
|
|
|
return overload;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string GCellGrid::_getTypeName () const
|
|
|
|
{
|
|
|
|
return _TName("GCellGrid");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string GCellGrid::_getString () const
|
|
|
|
{
|
|
|
|
return "<" + _getTypeName() + " "
|
|
|
|
+ getString(getRows()) + "x" + getString(getColumns()) + ">";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GCellGrid::_xmlWrite ( ostream& o )
|
|
|
|
{
|
|
|
|
updateDensity ();
|
|
|
|
|
|
|
|
o << "<GCellGrid Cell=\"" << getCell()->getName() << "\">" << endl;
|
|
|
|
o << "<!-- GRID Lower Left Corner Density -->" << endl;
|
|
|
|
o << "<!-- column row XMin YMin hor ver con -->" << endl;
|
|
|
|
|
|
|
|
unsigned int row = 0;
|
|
|
|
forEach ( GCell*, gcell, getGCells() ) {
|
|
|
|
if ( gcell->getRow() > row ) {
|
|
|
|
o << endl;
|
|
|
|
o << "<!-- column row XMin YMin hor ver con -->" << endl;
|
|
|
|
row = gcell->getRow();
|
|
|
|
}
|
|
|
|
|
|
|
|
o << " "; gcell->_xmlWrite ( o ); o << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
o << "</GCellGrid>" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Record* GCellGrid::_getRecord () const
|
|
|
|
{
|
|
|
|
Record* record = Grid<GCell>::_getRecord ();
|
|
|
|
record->add ( getSlot ( "_katabatic", _katabatic ) );
|
|
|
|
return record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // End of Katabatic namespace.
|