* ./katabatic:
- Change: In loadGlobalRouting(), more exlicit message as to why a net is
filtered out the routing set (POWER, GROUND, CLOCK or BLOCKAGE).
- New: ChipTool, module with utilities specific to chip routing. Containing
a function to pre-break wires around a block.
- New: In loadGlobalRouting/GCellConfiguration, adds supports for RoutingPad
connected on chip's pad.
- New: In GCellGrid/GCell, can compute the density in three modes: average,
max of H/V and max of layer. Currently implemented in getMaxHVDensity(),
should be unificated with getDensity(). Used for display purposes.
- Bug: In AutoContact, when splitting a contact, add a specific check for
"one layer span".
- Bug: In AutoSegment::canMoveUp(), do not move up fixed segments.
2010-11-16 07:59:38 -06:00
|
|
|
|
|
|
|
// -*- C++ -*-
|
|
|
|
//
|
|
|
|
// This file is part of the Coriolis Software.
|
|
|
|
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
|
|
|
//
|
|
|
|
// ===================================================================
|
|
|
|
//
|
|
|
|
// $Id$
|
|
|
|
//
|
|
|
|
// x-----------------------------------------------------------------x
|
|
|
|
// | |
|
|
|
|
// | C O R I O L I S |
|
|
|
|
// | K a t a b a t i c - Routing Toolbox |
|
|
|
|
// | |
|
|
|
|
// | Author : Jean-Paul CHAPUT |
|
|
|
|
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
|
|
|
// | =============================================================== |
|
|
|
|
// | C++ Module : "./ChipTools.cpp" |
|
|
|
|
// | *************************************************************** |
|
|
|
|
// | U p d a t e s |
|
|
|
|
// | |
|
|
|
|
// x-----------------------------------------------------------------x
|
|
|
|
|
|
|
|
|
* ./katabatic:
- New: ChipTools, regroup all datas and utilities to manage a full-chip
design.
- Change: In LoadGrByNet/GCellConfiguration::_GCell_xG_1Pad(), uses straight
perpandicular wires on top & right pads. The GCells under those connectors
are fully saturated, wires must go out as straight as possible.
- Change: In AutoHorizontal/AutoVertical, update the "terminal" flag after
slackening. This is to avoid global that are no longer connected to
terminals behave as such.
- Change: In AutoSegment::canMoveUp() & canPivotUp(), prevent all local segments
to go up. This is to avoid cluttering upper levels with small segments.
- Change: In GCellConfiguration, for xG_xL3, detect straight vertical topologies
and for them to be fixed (new flag FIXED_GLOBAL set by the topological
builder instead of the constructor). This prevent the router to do
stupid things...
To sets the "Fixed" flag *after* the axis of global segments have been
positionned correctly adds a "_toFixGlobals" static table lookup.
- Change: In GCell::stepDesaturate(), if less than one free track remains in
the upper layer, do not move up the segment. This allows from a minimum
free room for expansion.
- Change: In GCell::_getString(), display indexes and layer names in various
saturation tables.
- Change: In AutoSegment, allow move up of local Segment. ::moveUp() and
::canMoveUp() arguments go from booleans to flags, which are more
explicits.
2010-12-04 09:25:18 -06:00
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
* ./katabatic:
- Change: In loadGlobalRouting(), more exlicit message as to why a net is
filtered out the routing set (POWER, GROUND, CLOCK or BLOCKAGE).
- New: ChipTool, module with utilities specific to chip routing. Containing
a function to pre-break wires around a block.
- New: In loadGlobalRouting/GCellConfiguration, adds supports for RoutingPad
connected on chip's pad.
- New: In GCellGrid/GCell, can compute the density in three modes: average,
max of H/V and max of layer. Currently implemented in getMaxHVDensity(),
should be unificated with getDensity(). Used for display purposes.
- Bug: In AutoContact, when splitting a contact, add a specific check for
"one layer span".
- Bug: In AutoSegment::canMoveUp(), do not move up fixed segments.
2010-11-16 07:59:38 -06:00
|
|
|
#include "hurricane/Warning.h"
|
|
|
|
#include "hurricane/Bug.h"
|
|
|
|
#include "hurricane/DataBase.h"
|
|
|
|
#include "hurricane/Technology.h"
|
|
|
|
#include "hurricane/Horizontal.h"
|
|
|
|
#include "hurricane/Vertical.h"
|
|
|
|
#include "crlcore/RoutingGauge.h"
|
|
|
|
#include "crlcore/AllianceFramework.h"
|
|
|
|
#include "katabatic/Session.h"
|
|
|
|
#include "katabatic/AutoContact.h"
|
|
|
|
#include "katabatic/AutoSegment.h"
|
|
|
|
#include "katabatic/AutoHorizontal.h"
|
|
|
|
#include "katabatic/AutoVertical.h"
|
|
|
|
#include "katabatic/GCell.h"
|
|
|
|
#include "katabatic/GCellGrid.h"
|
|
|
|
#include "katabatic/KatabaticEngine.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace CRL;
|
|
|
|
using namespace Hurricane;
|
|
|
|
using namespace Katabatic;
|
|
|
|
|
|
|
|
|
|
|
|
enum SegmentType { LocalSegments=0x10, GlobalSegments=0x20 };
|
|
|
|
|
|
|
|
|
|
|
|
bool isChip ( Cell* cell, Instance*& core )
|
|
|
|
{
|
|
|
|
AllianceFramework* af = AllianceFramework::get();
|
|
|
|
int pads = 0;
|
|
|
|
int cores = 0;
|
|
|
|
|
|
|
|
forEach ( Instance*, iinstance, cell->getInstances() ) {
|
|
|
|
if ( af->isPad(iinstance->getMasterCell()) )
|
|
|
|
++pads;
|
|
|
|
else {
|
|
|
|
++cores;
|
|
|
|
core = *iinstance;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (pads > 0) and (cores == 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void breakSegments ( GCell* begin, GCell* end, Layer::Mask mask, unsigned int flags )
|
|
|
|
{
|
|
|
|
for ( GCell* gcell=begin ; gcell != NULL ; ) {
|
|
|
|
ltrace(200) << "Pre-break in " << gcell << endl;
|
|
|
|
|
|
|
|
if ( (flags & Constant::Horizontal) and (flags & GlobalSegments) ) {
|
|
|
|
vector<AutoSegment*>* hsegments = gcell->getHSegments();
|
|
|
|
for ( size_t i=0 ; i<(*hsegments).size() ; ++i ) {
|
|
|
|
if ( not ((*hsegments)[i]->getLayer()->getMask() & mask) ) continue;
|
|
|
|
|
|
|
|
ltrace(200) << "Pre-break: " << (*hsegments)[i] << " @" << gcell << endl;
|
|
|
|
(*hsegments)[i]->makeDogLeg ( gcell, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( gcell == end ) break;
|
|
|
|
gcell = gcell->getUp();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (flags & Constant::Vertical) and (flags & GlobalSegments) ) {
|
|
|
|
vector<AutoSegment*>* vsegments = gcell->getVSegments();
|
|
|
|
for ( size_t i=0 ; i<(*vsegments).size() ; ++i ) {
|
|
|
|
if ( not ((*vsegments)[i]->getLayer()->getMask() & mask) ) continue;
|
|
|
|
|
|
|
|
ltrace(200) << "Pre-break: " << (*vsegments)[i] << " @" << gcell << endl;
|
|
|
|
(*vsegments)[i]->makeDogLeg ( gcell, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( gcell == end ) break;
|
|
|
|
gcell = gcell->getUp();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( flags & GlobalSegments ) {
|
|
|
|
vector<AutoContact*>* contacts = gcell->getContacts();
|
|
|
|
vector<AutoSegment*> segments;
|
|
|
|
for ( size_t i=0 ; i<contacts->size() ; i++ ) {
|
|
|
|
forEach ( Component*, component, (*contacts)[i]->getSlaveComponents() ) {
|
|
|
|
Segment* segment = dynamic_cast<Segment*>(*component);
|
|
|
|
AutoSegment* autoSegment = Session::lookup ( segment );
|
|
|
|
|
|
|
|
if ( autoSegment and (autoSegment->getDirection() & flags) )
|
|
|
|
segments.push_back ( autoSegment );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( size_t i=0 ; i<segments.size() ; ++i ) {
|
|
|
|
ltrace(200) << "Pre-break: "
|
|
|
|
<< segments[i]->getDirection() << "&" << flags
|
|
|
|
<< " " << segments[i] << endl;
|
|
|
|
segments[i]->makeDogLeg ( gcell, true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Session::revalidate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} // End of anonymous namespace.
|
|
|
|
|
|
|
|
|
|
|
|
namespace Katabatic {
|
|
|
|
|
|
|
|
|
|
|
|
void KatabaticEngine::slackenBorder ( Box bb, Layer::Mask mask, unsigned int flags )
|
|
|
|
{
|
|
|
|
GCell* begin = getGCellGrid()->getGCell ( Point(bb.getXMin(),bb.getYMin()) );
|
|
|
|
GCell* end = getGCellGrid()->getGCell ( Point(bb.getXMin(),bb.getYMax()) );
|
|
|
|
|
|
|
|
breakSegments ( begin, end, mask, flags );
|
|
|
|
|
|
|
|
begin = getGCellGrid()->getGCell ( Point(bb.getXMax(),bb.getYMin()) );
|
|
|
|
end = getGCellGrid()->getGCell ( Point(bb.getXMax(),bb.getYMax()) );
|
|
|
|
|
|
|
|
breakSegments ( begin, end, mask, flags );
|
|
|
|
|
|
|
|
Session::revalidate ();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KatabaticEngine::slackenBlockIos ( Instance* core )
|
|
|
|
{
|
|
|
|
cmess1 << " o Slackening IOs of <" << core->getName() << ">." << endl;
|
|
|
|
|
|
|
|
Layer::Mask mask = Session::getRoutingLayer(1)->getMask();
|
|
|
|
slackenBorder ( core->getBoundingBox().inflate(DbU::lambda(50.0))
|
|
|
|
, mask
|
|
|
|
, GlobalSegments|Constant::Horizontal
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void KatabaticEngine::chipPrep ()
|
|
|
|
{
|
* ./katabatic:
- New: ChipTools, regroup all datas and utilities to manage a full-chip
design.
- Change: In LoadGrByNet/GCellConfiguration::_GCell_xG_1Pad(), uses straight
perpandicular wires on top & right pads. The GCells under those connectors
are fully saturated, wires must go out as straight as possible.
- Change: In AutoHorizontal/AutoVertical, update the "terminal" flag after
slackening. This is to avoid global that are no longer connected to
terminals behave as such.
- Change: In AutoSegment::canMoveUp() & canPivotUp(), prevent all local segments
to go up. This is to avoid cluttering upper levels with small segments.
- Change: In GCellConfiguration, for xG_xL3, detect straight vertical topologies
and for them to be fixed (new flag FIXED_GLOBAL set by the topological
builder instead of the constructor). This prevent the router to do
stupid things...
To sets the "Fixed" flag *after* the axis of global segments have been
positionned correctly adds a "_toFixGlobals" static table lookup.
- Change: In GCell::stepDesaturate(), if less than one free track remains in
the upper layer, do not move up the segment. This allows from a minimum
free room for expansion.
- Change: In GCell::_getString(), display indexes and layer names in various
saturation tables.
- Change: In AutoSegment, allow move up of local Segment. ::moveUp() and
::canMoveUp() arguments go from booleans to flags, which are more
explicits.
2010-12-04 09:25:18 -06:00
|
|
|
if ( isChip() ) {
|
|
|
|
// slackenBlockIos ( _core );
|
|
|
|
|
|
|
|
// cmess1 << " o Slackening Pads-connected segments." << endl;
|
|
|
|
// slackenBorder ( _cell->getBoundingBox().inflate(DbU::lambda(-425.0))
|
|
|
|
// , Session::getRoutingLayer(3)->getMask()
|
|
|
|
// , GlobalSegments|LocalSegments|Constant::Horizontal
|
|
|
|
// );
|
|
|
|
// slackenBorder ( _cell->getBoundingBox().inflate(DbU::lambda(-425.0))
|
|
|
|
// , Session::getRoutingLayer(1)->getMask()
|
|
|
|
// , GlobalSegments|Constant::Horizontal
|
|
|
|
// );
|
* ./katabatic:
- Change: In loadGlobalRouting(), more exlicit message as to why a net is
filtered out the routing set (POWER, GROUND, CLOCK or BLOCKAGE).
- New: ChipTool, module with utilities specific to chip routing. Containing
a function to pre-break wires around a block.
- New: In loadGlobalRouting/GCellConfiguration, adds supports for RoutingPad
connected on chip's pad.
- New: In GCellGrid/GCell, can compute the density in three modes: average,
max of H/V and max of layer. Currently implemented in getMaxHVDensity(),
should be unificated with getDensity(). Used for display purposes.
- Bug: In AutoContact, when splitting a contact, add a specific check for
"one layer span".
- Bug: In AutoSegment::canMoveUp(), do not move up fixed segments.
2010-11-16 07:59:38 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
* ./katabatic:
- New: ChipTools, regroup all datas and utilities to manage a full-chip
design.
- Change: In LoadGrByNet/GCellConfiguration::_GCell_xG_1Pad(), uses straight
perpandicular wires on top & right pads. The GCells under those connectors
are fully saturated, wires must go out as straight as possible.
- Change: In AutoHorizontal/AutoVertical, update the "terminal" flag after
slackening. This is to avoid global that are no longer connected to
terminals behave as such.
- Change: In AutoSegment::canMoveUp() & canPivotUp(), prevent all local segments
to go up. This is to avoid cluttering upper levels with small segments.
- Change: In GCellConfiguration, for xG_xL3, detect straight vertical topologies
and for them to be fixed (new flag FIXED_GLOBAL set by the topological
builder instead of the constructor). This prevent the router to do
stupid things...
To sets the "Fixed" flag *after* the axis of global segments have been
positionned correctly adds a "_toFixGlobals" static table lookup.
- Change: In GCell::stepDesaturate(), if less than one free track remains in
the upper layer, do not move up the segment. This allows from a minimum
free room for expansion.
- Change: In GCell::_getString(), display indexes and layer names in various
saturation tables.
- Change: In AutoSegment, allow move up of local Segment. ::moveUp() and
::canMoveUp() arguments go from booleans to flags, which are more
explicits.
2010-12-04 09:25:18 -06:00
|
|
|
ChipTools::ChipTools ( Cell* cell )
|
|
|
|
: _cell (cell)
|
|
|
|
, _core (NULL)
|
|
|
|
, _isChip (false)
|
|
|
|
, _chipBb (cell->getBoundingBox())
|
|
|
|
, _leftPadsBb ()
|
|
|
|
, _rightPadsBb ()
|
|
|
|
, _topPadsBb ()
|
|
|
|
, _bottomPadsBb()
|
|
|
|
, _chipCorona ()
|
|
|
|
{
|
|
|
|
_isChip = ::isChip ( _cell, _core );
|
|
|
|
|
|
|
|
if ( _isChip ) {
|
|
|
|
// Ugly: hard-coded pads height.
|
|
|
|
const DbU::Unit padHeight = DbU::lambda(400.0);
|
|
|
|
|
|
|
|
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() );
|
|
|
|
|
|
|
|
cmess1 << " o Design is a full chip." << endl;
|
|
|
|
cmess1 << " - Core: <" << _core->getName() << ">/<"
|
|
|
|
<< _core->getMasterCell()->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 ( "_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;
|
|
|
|
}
|
|
|
|
|
* ./katabatic:
- Change: In loadGlobalRouting(), more exlicit message as to why a net is
filtered out the routing set (POWER, GROUND, CLOCK or BLOCKAGE).
- New: ChipTool, module with utilities specific to chip routing. Containing
a function to pre-break wires around a block.
- New: In loadGlobalRouting/GCellConfiguration, adds supports for RoutingPad
connected on chip's pad.
- New: In GCellGrid/GCell, can compute the density in three modes: average,
max of H/V and max of layer. Currently implemented in getMaxHVDensity(),
should be unificated with getDensity(). Used for display purposes.
- Bug: In AutoContact, when splitting a contact, add a specific check for
"one layer span".
- Bug: In AutoSegment::canMoveUp(), do not move up fixed segments.
2010-11-16 07:59:38 -06:00
|
|
|
|
|
|
|
} // End of Katabatic namespace.
|