Added core2chip support for Phenitec80.
This commit degrades the run success rate of ARMv2a to 87% (40 iters). * New: In CRLcore/etc/.../kite.conf, add configuration parameters: katana.termSatReservedlocal katana.termSatthreshold for the new edge capacity computation system. * New: In CRLcore/etc/symbolic/phenitec06/, add support for N. Shimizu small I/O pads (supplied in phlib80). Tune various parameters of Anabatic/Katana to increase routing success. * Change: In CRLcore/alliance/ap/ApParser, make Pin external components, so RoutingPad will be build upon in global routing. Do not complain when a I/O pad has a physical instance that did not exists in the netlist. Just create it (appeared in phlib80). When no netlist instance exists in a pad, the pad Cell is still considered as terminal. * New: In Etesian::BloatCells, new profile named "3metals" better suited for two routing metals technologies (i.e. Phenitec). * New: In Anabatic::RawGCellsUnder, new CTOR which take only source & target points instead of a segment. Needed to manage wide segment for which the axis to consider is not that of the segment (one axis for each track it intersect). * New: In Anabatic::GCell, add a RoutingPad count attribute, for Edge reservation computation. * New: In AnabaticEngine::computeEdgeCapacities(), instead of decreasing all edges of a fixed amount (hTrackReservedLocal), guess the GCell cluttering from the number of RoutingPads that it contains. For non-saturated GCells, the four edges are decreased by the number of RoutingPads. We use the maximum from the two neigboring GCells. The hTrackReservedLocal parameter is now used only as a *maximum* that the edge reservation can reach. If a GCell is saturated (more than 8 RoutingPads, the saturation is propagated horizontally to 2 neigboring GCells). * Change: In AutoContactTerminal::getNativeConstraintBox(), use a more flexible gauge name matching for terminal vertical extensions correction. Namely, match all "msxlib*" kind of gauges. * Change: In AutoSegment::setAxis(), add the ability to force the axis position, even if it is a non-canonical segment. Maybe needed in the initialisation steo, before the first canonisation is performed. * New: In NetBuilder, added new methods _do_1G_1PinM1() and _do_2G_1PinM1(), to manage coronas for Phenitec designs. To avoid various side effects from segments being too close from the north / east side of the routing area, make those segments fixeds. * Change: In KatanaEngine::annotateGlobalGraph(), the management of wide wires was wrong. The axis to use to find the underlying GCells is the one of the track, not of the segment. This was creating bad edge capacity computation under the power ring of a block and subsequently routing failures. * New: In Kanata::Manipulator, added method reprocessParallels(), not used though, but keep it anyway, might be of use later... * New: In Kanata::Manipulator, added method avoidBlockage() for terminal METAL2 in non-preferred direction, restrict the terminal and turn constraint box at the current position of the perpandicular, so it doesn't create a deadlock in METAL2. * Change: In SegmentFsm::conflictSolveByPlaceds(), if we cannot break using the whole overlap, try the first atomic overlap. * New: In SegmentFsm::_slackenStrap(), manage conflict between a non-prefered segment and a blockage, this when to call avoidBlockage()... * New: In Katana::Configuration, management of the new edge computation parameters: katana.termSatReservedlocal katana.termSatthreshold * New: In Cumulus/plugins/Core2Chip, support for Phenitec I/O pads.
This commit is contained in:
parent
c6ea1bccdd
commit
24dedce09c
|
@ -170,28 +170,67 @@ namespace Anabatic {
|
||||||
|
|
||||||
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Segment* segment )
|
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Segment* segment )
|
||||||
{
|
{
|
||||||
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(): " << segment << endl;
|
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(Segment*): " << segment << endl;
|
||||||
|
|
||||||
Box gcellsArea = engine->getCell()->getAbutmentBox();
|
commonCtor( engine, segment->getSourcePosition(), segment->getTargetPosition() );
|
||||||
Point sourcePosition = segment->getSourcePosition();
|
|
||||||
Point targetPosition = segment->getTargetPosition();
|
|
||||||
|
|
||||||
if ( (sourcePosition.getX() > gcellsArea.getXMax())
|
cdebug_tabw(112,-1);
|
||||||
or (sourcePosition.getY() > gcellsArea.getYMax())
|
}
|
||||||
or (targetPosition.getX() <= gcellsArea.getXMin())
|
|
||||||
or (targetPosition.getY() <= gcellsArea.getYMin()) ) {
|
|
||||||
cerr << Error( "RawGCellsUnder::RawGCellsUnder(): %s is completly outside the GCells area (ignored)."
|
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Point source, Point target )
|
||||||
, getString(segment).c_str()
|
{
|
||||||
|
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(Point,Point): s:"
|
||||||
|
<< source << " t:" << target << endl;
|
||||||
|
|
||||||
|
commonCtor( engine, source, target );
|
||||||
|
|
||||||
|
cdebug_tabw(112,-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawGCellsUnder::commonCtor ( const AnabaticEngine* engine, Point source, Point target )
|
||||||
|
{
|
||||||
|
cdebug_log(112,1) << "RawGCellsUnder::commontCtor(): s:" << source << " t:" << target << endl;
|
||||||
|
|
||||||
|
Box gcellsArea = engine->getCell()->getAbutmentBox();
|
||||||
|
DbU::Unit axis = 0;
|
||||||
|
Flags side = Flags::NoFlags;
|
||||||
|
|
||||||
|
if (source.getY() == target.getY()) {
|
||||||
|
side = Flags::EastSide;
|
||||||
|
axis = source.getY();
|
||||||
|
if (source.getX() > target.getX()) std::swap( source, target );
|
||||||
|
}
|
||||||
|
if (source.getX() == target.getX()) {
|
||||||
|
side = Flags::NorthSide;
|
||||||
|
axis = source.getX();
|
||||||
|
if (source.getY() > target.getY()) std::swap( source, target );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (side == Flags::NoFlags) {
|
||||||
|
cerr << Error( "RawGCellsUnder::commonCtor(): Points are neither horizontally nor vertically aligneds (ignored)."
|
||||||
) << endl;
|
) << endl;
|
||||||
cdebug_tabw(112,-1);
|
cdebug_tabw(112,-1);
|
||||||
DebugSession::close();
|
DebugSession::close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbU::Unit xsource = std::max( sourcePosition.getX(), gcellsArea.getXMin() );
|
if ( (source.getX() > gcellsArea.getXMax())
|
||||||
DbU::Unit ysource = std::max( sourcePosition.getY(), gcellsArea.getYMin() );
|
or (source.getY() > gcellsArea.getYMax())
|
||||||
DbU::Unit xtarget = std::min( targetPosition.getX(), gcellsArea.getXMax() );
|
or (target.getX() <= gcellsArea.getXMin())
|
||||||
DbU::Unit ytarget = std::min( targetPosition.getY(), gcellsArea.getYMax() );
|
or (target.getY() <= gcellsArea.getYMin()) ) {
|
||||||
|
cerr << Error( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored)."
|
||||||
|
) << endl;
|
||||||
|
cdebug_tabw(112,-1);
|
||||||
|
DebugSession::close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbU::Unit xsource = std::max( source.getX(), gcellsArea.getXMin() );
|
||||||
|
DbU::Unit ysource = std::max( source.getY(), gcellsArea.getYMin() );
|
||||||
|
DbU::Unit xtarget = std::min( target.getX(), gcellsArea.getXMax() );
|
||||||
|
DbU::Unit ytarget = std::min( target.getY(), gcellsArea.getYMax() );
|
||||||
|
|
||||||
if (xtarget == gcellsArea.getXMax()) --xtarget;
|
if (xtarget == gcellsArea.getXMax()) --xtarget;
|
||||||
if (ytarget == gcellsArea.getYMax()) --ytarget;
|
if (ytarget == gcellsArea.getYMax()) --ytarget;
|
||||||
|
@ -200,16 +239,14 @@ namespace Anabatic {
|
||||||
GCell* gtarget = engine->getGCellUnder( xtarget, ytarget );
|
GCell* gtarget = engine->getGCellUnder( xtarget, ytarget );
|
||||||
|
|
||||||
if (not gsource) {
|
if (not gsource) {
|
||||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s source not under a GCell (ignored)."
|
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)."
|
||||||
, getString(segment).c_str()
|
|
||||||
) << endl;
|
) << endl;
|
||||||
cdebug_tabw(112,-1);
|
cdebug_tabw(112,-1);
|
||||||
DebugSession::close();
|
DebugSession::close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (not gtarget) {
|
if (not gtarget) {
|
||||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s target not under a GCell (ignored)."
|
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)."
|
||||||
, getString(segment).c_str()
|
|
||||||
) << endl;
|
) << endl;
|
||||||
cdebug_tabw(112,-1);
|
cdebug_tabw(112,-1);
|
||||||
DebugSession::close();
|
DebugSession::close();
|
||||||
|
@ -223,24 +260,6 @@ namespace Anabatic {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Flags side = Flags::NoFlags;
|
|
||||||
DbU::Unit axis = 0;
|
|
||||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( segment );
|
|
||||||
if (horizontal) {
|
|
||||||
side = Flags::EastSide;
|
|
||||||
axis = horizontal->getY();
|
|
||||||
|
|
||||||
if (horizontal->getSourceX() > horizontal->getTargetX())
|
|
||||||
std::swap( gsource, gtarget );
|
|
||||||
} else {
|
|
||||||
Vertical* vertical = dynamic_cast<Vertical*>( segment );
|
|
||||||
side = Flags::NorthSide;
|
|
||||||
axis = vertical->getX();
|
|
||||||
|
|
||||||
if (vertical->getSourceY() > vertical->getTargetY())
|
|
||||||
std::swap( gsource, gtarget );
|
|
||||||
}
|
|
||||||
|
|
||||||
cdebug_log(112,0) << "flags:" << side << " axis:" << DbU::getValueString(axis) << endl;
|
cdebug_log(112,0) << "flags:" << side << " axis:" << DbU::getValueString(axis) << endl;
|
||||||
|
|
||||||
Edge* edge = gsource->getEdgeAt( side, axis );
|
Edge* edge = gsource->getEdgeAt( side, axis );
|
||||||
|
@ -1406,6 +1425,83 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AnabaticEngine::computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat )
|
||||||
|
{
|
||||||
|
vector<RoutingPad*> rps;
|
||||||
|
vector<GCell*> saturateds;
|
||||||
|
const vector<NetData*>& netDatas = getNetOrdering();
|
||||||
|
|
||||||
|
for ( NetData* netData : netDatas ) {
|
||||||
|
for ( Component* component : netData->getNet()->getComponents() ) {
|
||||||
|
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
|
||||||
|
if (rp) rps.push_back( rp );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateSession::open();
|
||||||
|
|
||||||
|
for ( auto rp : rps ) {
|
||||||
|
if (not getConfiguration()->selectRpComponent(rp))
|
||||||
|
cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||||
|
|
||||||
|
Point center = rp->getBoundingBox().getCenter();
|
||||||
|
GCell* gcell = getGCellUnder( center );
|
||||||
|
|
||||||
|
if (not gcell) {
|
||||||
|
cerr << Error( "AnabaticEngine::computeEdgeCapacities(): %s\n"
|
||||||
|
" @%s of %s is not under any GCell.\n"
|
||||||
|
" It will be ignored so the edge capacity estimate may be wrong."
|
||||||
|
, getString(rp).c_str()
|
||||||
|
, getString(center).c_str()
|
||||||
|
, getString(rp->getNet()).c_str()
|
||||||
|
) << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcell->incRpCount( 1 );
|
||||||
|
if (gcell->getRpCount() == termSatThreshold) saturateds.push_back( gcell );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( GCell* gcell : getGCells() ) {
|
||||||
|
if (not gcell->isMatrix()) continue;
|
||||||
|
|
||||||
|
for ( Edge* edge : gcell->getEdges(Flags::EastSide|Flags::NorthSide) ) {
|
||||||
|
GCell* opposite = edge->getOpposite( gcell );
|
||||||
|
int maxReserved = maxHCap;
|
||||||
|
int reserved = std::max( gcell->getRpCount(), opposite->getRpCount() );
|
||||||
|
|
||||||
|
if (edge->isVertical()) maxReserved = maxVCap;
|
||||||
|
edge->reserveCapacity( std::min( maxReserved, reserved ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( GCell* gcell : saturateds ) {
|
||||||
|
GCell* neighbor = gcell;
|
||||||
|
for ( size_t i=0 ; i<2; ++i ) {
|
||||||
|
Edge* edge = neighbor->getWestEdge();
|
||||||
|
if (not edge) break;
|
||||||
|
|
||||||
|
if (edge->getReservedCapacity() < maxTermSat)
|
||||||
|
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
|
||||||
|
neighbor = neighbor->getWest();
|
||||||
|
}
|
||||||
|
neighbor = gcell;
|
||||||
|
for ( size_t i=0 ; i<2; ++i ) {
|
||||||
|
Edge* edge = neighbor->getEastEdge();
|
||||||
|
if (not edge) break;
|
||||||
|
|
||||||
|
if (edge->getReservedCapacity() < maxTermSat)
|
||||||
|
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
|
||||||
|
neighbor = neighbor->getEast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateSession::close();
|
||||||
|
|
||||||
|
//Breakpoint::stop( 1, "Edge capacities computeds." );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnabaticEngine::_check ( Net* net ) const
|
void AnabaticEngine::_check ( Net* net ) const
|
||||||
{
|
{
|
||||||
cdebug_log(149,1) << "Checking " << net << endl;
|
cdebug_log(149,1) << "Checking " << net << endl;
|
||||||
|
|
|
@ -194,7 +194,7 @@ namespace Anabatic {
|
||||||
// SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on
|
// SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on
|
||||||
// their extremities. Should modificate all the standard cells layout...
|
// their extremities. Should modificate all the standard cells layout...
|
||||||
// HARDCODED.
|
// HARDCODED.
|
||||||
if (Session::getRoutingGauge()->getName() == "msxlib")
|
if (getString(Session::getRoutingGauge()->getName()).substr(0,6) == "msxlib")
|
||||||
yborder -= DbU::fromLambda( 1.0 );
|
yborder -= DbU::fromLambda( 1.0 );
|
||||||
else
|
else
|
||||||
yborder -= DbU::fromLambda( 0.5 );
|
yborder -= DbU::fromLambda( 0.5 );
|
||||||
|
|
|
@ -1076,7 +1076,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AutoSegment::setAxis ( DbU::Unit axis, Flags flags )
|
void AutoSegment::setAxis ( DbU::Unit axis, Flags flags )
|
||||||
{
|
{
|
||||||
if (not isCanonical()) return;
|
if (not isCanonical() and not (flags & Flags::Force)) return;
|
||||||
|
|
||||||
if ( (axis == getAxis()) and not (flags & Flags::Realignate) ) return;
|
if ( (axis == getAxis()) and not (flags & Flags::Realignate) ) return;
|
||||||
|
|
||||||
|
|
|
@ -77,8 +77,8 @@ namespace Anabatic {
|
||||||
, _cg (NULL)
|
, _cg (NULL)
|
||||||
, _rg (NULL)
|
, _rg (NULL)
|
||||||
, _extensionCaps ()
|
, _extensionCaps ()
|
||||||
, _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
|
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble())
|
||||||
, _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt())
|
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt())
|
||||||
, _globalThreshold (0)
|
, _globalThreshold (0)
|
||||||
, _allowedDepth (0)
|
, _allowedDepth (0)
|
||||||
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
|
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
|
||||||
|
|
|
@ -118,6 +118,7 @@ namespace Anabatic {
|
||||||
const BaseFlags Flags::NoUpdate = (1L << 32);
|
const BaseFlags Flags::NoUpdate = (1L << 32);
|
||||||
const BaseFlags Flags::NorthPath = (1L << 33);
|
const BaseFlags Flags::NorthPath = (1L << 33);
|
||||||
const BaseFlags Flags::UseNonPref = (1L << 34);
|
const BaseFlags Flags::UseNonPref = (1L << 34);
|
||||||
|
const BaseFlags Flags::Force = (1L << 35);
|
||||||
|
|
||||||
|
|
||||||
Flags::~Flags ()
|
Flags::~Flags ()
|
||||||
|
|
|
@ -298,6 +298,7 @@ namespace Anabatic {
|
||||||
, _contacts ()
|
, _contacts ()
|
||||||
, _depth (Session::getRoutingGauge()->getDepth())
|
, _depth (Session::getRoutingGauge()->getDepth())
|
||||||
, _pinDepth (0)
|
, _pinDepth (0)
|
||||||
|
, _rpCount (0)
|
||||||
, _blockages (new DbU::Unit [_depth])
|
, _blockages (new DbU::Unit [_depth])
|
||||||
, _cDensity (0.0)
|
, _cDensity (0.0)
|
||||||
, _densities (new float [_depth])
|
, _densities (new float [_depth])
|
||||||
|
@ -1790,6 +1791,7 @@ namespace Anabatic {
|
||||||
string s = Super::_getString();
|
string s = Super::_getString();
|
||||||
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
|
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
|
||||||
s.insert( s.size()-1, " "+getString(_flags) );
|
s.insert( s.size()-1, " "+getString(_flags) );
|
||||||
|
s.insert( s.size()-1, " "+getString(_rpCount) );
|
||||||
/* string s = "<GCell at(" + DbU::getValueString(getXMin())
|
/* string s = "<GCell at(" + DbU::getValueString(getXMin())
|
||||||
+ "-" + DbU::getValueString(getYMin())
|
+ "-" + DbU::getValueString(getYMin())
|
||||||
+ "-" + DbU::getValueString(getXMax())
|
+ "-" + DbU::getValueString(getXMax())
|
||||||
|
|
|
@ -349,7 +349,7 @@ namespace Anabatic {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
|
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
|
||||||
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
|
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
|
||||||
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
|
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
|
||||||
|
|
||||||
if (not (*igcell)->isSaturated(depth)) {
|
if (not (*igcell)->isSaturated(depth)) {
|
||||||
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;
|
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;
|
||||||
|
|
|
@ -616,6 +616,8 @@ namespace Anabatic {
|
||||||
case Conn_4G: _do_xG(); break;
|
case Conn_4G: _do_xG(); break;
|
||||||
// End xG cascaded cases.
|
// End xG cascaded cases.
|
||||||
// Optimized specific cases.
|
// Optimized specific cases.
|
||||||
|
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
|
||||||
|
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
|
||||||
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
||||||
case Conn_2G_1PinM2:
|
case Conn_2G_1PinM2:
|
||||||
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
||||||
|
@ -628,7 +630,7 @@ namespace Anabatic {
|
||||||
default:
|
default:
|
||||||
if (not isTwoMetals())
|
if (not isTwoMetals())
|
||||||
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
||||||
" The global routing seems to be defective."
|
" The global routing seems to be defective."
|
||||||
, _connexity.connexity
|
, _connexity.connexity
|
||||||
, _connexity.fields.globals
|
, _connexity.fields.globals
|
||||||
, _connexity.fields.M1
|
, _connexity.fields.M1
|
||||||
|
@ -962,6 +964,20 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NetBuilder::_do_1G_1PinM1 ()
|
||||||
|
{
|
||||||
|
throw Error ( "%s::_do_1G_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NetBuilder::_do_2G_1PinM1 ()
|
||||||
|
{
|
||||||
|
throw Error ( "%s::_do_2G_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NetBuilder::_do_xG_1PinM2 ()
|
bool NetBuilder::_do_xG_1PinM2 ()
|
||||||
{
|
{
|
||||||
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "hurricane/RoutingPad.h"
|
#include "hurricane/RoutingPad.h"
|
||||||
#include "hurricane/RoutingPads.h"
|
#include "hurricane/RoutingPads.h"
|
||||||
#include "hurricane/Pad.h"
|
#include "hurricane/Pad.h"
|
||||||
|
#include "hurricane/Pin.h"
|
||||||
#include "hurricane/Plug.h"
|
#include "hurricane/Plug.h"
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
#include "hurricane/Instance.h"
|
#include "hurricane/Instance.h"
|
||||||
|
@ -54,6 +55,8 @@ namespace Anabatic {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
using Hurricane::Transformation;
|
using Hurricane::Transformation;
|
||||||
using Hurricane::Warning;
|
using Hurricane::Warning;
|
||||||
|
using Hurricane::Error;
|
||||||
|
using Hurricane::Pin;
|
||||||
|
|
||||||
|
|
||||||
NetBuilderHV::NetBuilderHV ()
|
NetBuilderHV::NetBuilderHV ()
|
||||||
|
@ -105,7 +108,7 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-M1 terminal or punctual M1 protections.
|
// Non-M1 terminal or punctual M1 protections.
|
||||||
if ((rpDepth != 0) or (sourcePosition == targetPosition)) {
|
if ( ((rpDepth != 0) or (sourcePosition == targetPosition)) and not (flags & NoProtect) ) {
|
||||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||||
if (irp == getRpLookup().end()) {
|
if (irp == getRpLookup().end()) {
|
||||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||||
|
@ -499,15 +502,185 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NetBuilderHV::_do_1G_1PinM1 ()
|
||||||
|
{
|
||||||
|
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||||
|
|
||||||
|
AutoContact* rpSourceContact = NULL;
|
||||||
|
AutoContact* rpContactTarget = NULL;
|
||||||
|
AutoContact* turn = NULL;
|
||||||
|
|
||||||
|
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoProtect );
|
||||||
|
|
||||||
|
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
|
||||||
|
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||||
|
if ( (pinDir == Pin::AccessDirection::NORTH)
|
||||||
|
or (pinDir == Pin::AccessDirection::SOUTH) ) {
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getRoutingLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, turn, Flags::Vertical|Flags::UseNonPref );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment* horizontal = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
|
||||||
|
DbU::Unit axis = getGCell()->getYMax() - Session::getDHorizontalPitch();
|
||||||
|
if (pinDir == Pin::AccessDirection::SOUTH)
|
||||||
|
axis = getGCell()->getYMin() + Session::getDHorizontalPitch();
|
||||||
|
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||||
|
|
||||||
|
horizontal->setAxis( axis, Flags::Force );
|
||||||
|
horizontal->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||||
|
cdebug_log(145,0) << horizontal << endl;
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getRoutingLayer(1) );
|
||||||
|
AutoSegment* vertical = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
vertical->setAxis( pin->getX(), Flags::Force );
|
||||||
|
vertical->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||||
|
cdebug_log(145,0) << vertical << endl;
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
horizontal = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
horizontal->setAxis( axis, Flags::Force );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
} else {
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (east() or west()) {
|
||||||
|
rpSourceContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment* vertical = AutoSegment::create( turn, rpSourceContact, Flags::Vertical );
|
||||||
|
|
||||||
|
DbU::Unit axis = getGCell()->getXMax() - Session::getDVerticalPitch();
|
||||||
|
if (pinDir == Pin::AccessDirection::WEST)
|
||||||
|
axis = getGCell()->getXMin() + Session::getDVerticalPitch();
|
||||||
|
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||||
|
|
||||||
|
vertical->setAxis( axis, Flags::Force );
|
||||||
|
vertical->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||||
|
|
||||||
|
turn = rpSourceContact;
|
||||||
|
}
|
||||||
|
setBothCornerContacts( turn );
|
||||||
|
|
||||||
|
cdebug_tabw(145,-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NetBuilderHV::_do_2G_1PinM1 ()
|
||||||
|
{
|
||||||
|
cdebug_log(145,1) << getTypeName() << "::_do_2G_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||||
|
|
||||||
|
AutoContact* rpSourceContact = NULL;
|
||||||
|
AutoContact* rpContactTarget = NULL;
|
||||||
|
AutoContact* tee = NULL;
|
||||||
|
AutoContact* turn = NULL;
|
||||||
|
|
||||||
|
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoProtect );
|
||||||
|
|
||||||
|
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
|
||||||
|
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||||
|
if ( (pinDir == Pin::AccessDirection::NORTH)
|
||||||
|
or (pinDir == Pin::AccessDirection::SOUTH) ) {
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getRoutingLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, turn, Flags::Vertical|Flags::UseNonPref );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment* horizontal = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
|
||||||
|
DbU::Unit axis = getGCell()->getYMax() - Session::getDHorizontalPitch();
|
||||||
|
if (pinDir == Pin::AccessDirection::SOUTH)
|
||||||
|
axis = getGCell()->getYMin() + Session::getDHorizontalPitch();
|
||||||
|
horizontal->setAxis( axis, Flags::Force );
|
||||||
|
horizontal->setFlags( AutoSegment::SegFixed );
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getRoutingLayer(1) );
|
||||||
|
AutoSegment* vertical = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
vertical->setFlags( AutoSegment::SegFixed );
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
horizontal = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
horizontal->setAxis( axis, Flags::Force );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
turn = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (east() and west()) {
|
||||||
|
// Pin must be North or South.
|
||||||
|
tee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, tee, Flags::Vertical );
|
||||||
|
} else if (north() and south()) {
|
||||||
|
// Pin must be East or West.
|
||||||
|
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, tee, Flags::Horizontal );
|
||||||
|
} else {
|
||||||
|
if ( (pinDir == Pin::AccessDirection::EAST)
|
||||||
|
or (pinDir == Pin::AccessDirection::WEST) ) {
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
}
|
||||||
|
|
||||||
|
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment* vertical = AutoSegment::create( rpSourceContact, tee, Flags::Vertical );
|
||||||
|
|
||||||
|
if ( (pinDir == Pin::AccessDirection::EAST)
|
||||||
|
or (pinDir == Pin::AccessDirection::WEST) ) {
|
||||||
|
DbU::Unit axis = getGCell()->getXMax() - Session::getDVerticalPitch();
|
||||||
|
if (pinDir == Pin::AccessDirection::WEST)
|
||||||
|
axis = getGCell()->getXMin() + Session::getDVerticalPitch();
|
||||||
|
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||||
|
|
||||||
|
vertical->setAxis( axis, Flags::Force );
|
||||||
|
vertical->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setBothCornerContacts( tee );
|
||||||
|
|
||||||
|
cdebug_tabw(145,-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NetBuilderHV::_do_xG_1PinM2 ()
|
bool NetBuilderHV::_do_xG_1PinM2 ()
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||||
|
|
||||||
AutoContact* rpSourceContact = NULL;
|
AutoContact* rpSourceContact = NULL;
|
||||||
AutoContact* rpContactTarget = NULL;
|
AutoContact* rpContactTarget = NULL;
|
||||||
|
AutoContact* turn = NULL;
|
||||||
|
|
||||||
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoFlags );
|
doRp_AutoContacts( getGCell(), getRoutingPads()[0], rpSourceContact, rpContactTarget, NoFlags );
|
||||||
|
|
||||||
|
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
|
||||||
|
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||||
|
if ( (pinDir == Pin::AccessDirection::EAST)
|
||||||
|
or (pinDir == Pin::AccessDirection::WEST) ) {
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment::create( rpSourceContact, turn, Flags::Horizontal );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
|
||||||
|
turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
AutoSegment* vertical = AutoSegment::create( rpSourceContact, turn, Flags::Vertical );
|
||||||
|
rpSourceContact = turn;
|
||||||
|
|
||||||
|
DbU::Unit axis = getGCell()->getXMax() - Session::getDVerticalPitch();
|
||||||
|
if (pinDir == Pin::AccessDirection::WEST)
|
||||||
|
axis = getGCell()->getXMin() + Session::getDVerticalPitch();
|
||||||
|
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||||
|
|
||||||
|
vertical->setAxis( axis, Flags::Force );
|
||||||
|
vertical->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||||
|
}
|
||||||
|
|
||||||
if (getConnexity().fields.globals == 2) {
|
if (getConnexity().fields.globals == 2) {
|
||||||
if (west() and south()) {
|
if (west() and south()) {
|
||||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||||
|
|
|
@ -68,6 +68,8 @@ namespace Anabatic {
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
RawGCellsUnder ( const AnabaticEngine*, Segment* );
|
RawGCellsUnder ( const AnabaticEngine*, Segment* );
|
||||||
|
RawGCellsUnder ( const AnabaticEngine*, Point source, Point target );
|
||||||
|
void commonCtor ( const AnabaticEngine*, Point source, Point target );
|
||||||
inline bool empty () const;
|
inline bool empty () const;
|
||||||
inline size_t size () const;
|
inline size_t size () const;
|
||||||
inline GCell* gcellAt ( size_t ) const;
|
inline GCell* gcellAt ( size_t ) const;
|
||||||
|
@ -208,6 +210,7 @@ namespace Anabatic {
|
||||||
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
|
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||||
inline GCell* getGCellUnder ( Point ) const;
|
inline GCell* getGCellUnder ( Point ) const;
|
||||||
inline GCellsUnder getGCellsUnder ( Segment* ) const;
|
inline GCellsUnder getGCellsUnder ( Segment* ) const;
|
||||||
|
inline GCellsUnder getGCellsUnder ( Point source, Point target ) const;
|
||||||
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) const;
|
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) const;
|
||||||
Interval getUSide ( Flags direction ) const;
|
Interval getUSide ( Flags direction ) const;
|
||||||
int getCapacity ( Interval, Flags ) const;
|
int getCapacity ( Interval, Flags ) const;
|
||||||
|
@ -255,6 +258,7 @@ namespace Anabatic {
|
||||||
inline void setSaturateRp ( size_t );
|
inline void setSaturateRp ( size_t );
|
||||||
inline void setBlockageNet ( Net* );
|
inline void setBlockageNet ( Net* );
|
||||||
void chipPrep ();
|
void chipPrep ();
|
||||||
|
void computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat );
|
||||||
void setupSpecialNets ();
|
void setupSpecialNets ();
|
||||||
size_t setupPreRouteds ();
|
size_t setupPreRouteds ();
|
||||||
void loadGlobalRouting ( uint32_t method );
|
void loadGlobalRouting ( uint32_t method );
|
||||||
|
@ -346,6 +350,7 @@ namespace Anabatic {
|
||||||
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
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 GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
|
||||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
|
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
|
||||||
|
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); }
|
||||||
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
|
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
|
||||||
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
||||||
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
||||||
|
|
|
@ -101,6 +101,7 @@ namespace Anabatic {
|
||||||
static const BaseFlags NoUpdate ;
|
static const BaseFlags NoUpdate ;
|
||||||
static const BaseFlags NorthPath ;
|
static const BaseFlags NorthPath ;
|
||||||
static const BaseFlags UseNonPref ;
|
static const BaseFlags UseNonPref ;
|
||||||
|
static const BaseFlags Force ;
|
||||||
public:
|
public:
|
||||||
inline Flags ( uint64_t flags = NoFlags );
|
inline Flags ( uint64_t flags = NoFlags );
|
||||||
inline Flags ( const Hurricane::BaseFlags& );
|
inline Flags ( const Hurricane::BaseFlags& );
|
||||||
|
|
|
@ -217,6 +217,7 @@ namespace Anabatic {
|
||||||
bool hasFreeTrack ( size_t depth, float reserve ) const;
|
bool hasFreeTrack ( size_t depth, float reserve ) const;
|
||||||
inline size_t getDepth () const;
|
inline size_t getDepth () const;
|
||||||
size_t getNetCount () const;
|
size_t getNetCount () const;
|
||||||
|
inline int getRpCount () const;
|
||||||
int getHCapacity () const;
|
int getHCapacity () const;
|
||||||
int getVCapacity () const;
|
int getVCapacity () const;
|
||||||
int getCapacity ( size_t depth ) const;
|
int getCapacity ( size_t depth ) const;
|
||||||
|
@ -264,7 +265,7 @@ namespace Anabatic {
|
||||||
bool stepNetDesaturate ( size_t depth
|
bool stepNetDesaturate ( size_t depth
|
||||||
, set<Net*>& globalNets
|
, set<Net*>& globalNets
|
||||||
, Set& invalidateds );
|
, Set& invalidateds );
|
||||||
|
inline void incRpCount ( int );
|
||||||
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
|
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
|
||||||
// Misc. functions.
|
// Misc. functions.
|
||||||
inline const Flags& flags () const;
|
inline const Flags& flags () const;
|
||||||
|
@ -321,6 +322,7 @@ namespace Anabatic {
|
||||||
vector<AutoContact*> _contacts;
|
vector<AutoContact*> _contacts;
|
||||||
size_t _depth;
|
size_t _depth;
|
||||||
size_t _pinDepth;
|
size_t _pinDepth;
|
||||||
|
int _rpCount;
|
||||||
DbU::Unit* _blockages;
|
DbU::Unit* _blockages;
|
||||||
float _cDensity;
|
float _cDensity;
|
||||||
float* _densities;
|
float* _densities;
|
||||||
|
@ -374,7 +376,8 @@ namespace Anabatic {
|
||||||
|
|
||||||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||||
inline size_t GCell::getDepth () const { return _depth; }
|
inline size_t GCell::getDepth () const { return _depth; }
|
||||||
|
inline int GCell::getRpCount () const { return _rpCount; }
|
||||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||||
|
@ -418,6 +421,10 @@ namespace Anabatic {
|
||||||
return Interval( getXMin(), getConstraintXMax(shrink) );
|
return Interval( getXMin(), getConstraintXMax(shrink) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void GCell::incRpCount ( int delta )
|
||||||
|
{ _rpCount = (_rpCount + delta > 0) ? (_rpCount + delta) : 0; }
|
||||||
|
|
||||||
|
|
||||||
inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
|
inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
|
||||||
{ _observable.setObserver( slot, observer ); }
|
{ _observable.setObserver( slot, observer ); }
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace Anabatic {
|
||||||
, EastBound = (1 << 15)
|
, EastBound = (1 << 15)
|
||||||
, Middle = (1 << 16)
|
, Middle = (1 << 16)
|
||||||
, UseNonPref = (1 << 17)
|
, UseNonPref = (1 << 17)
|
||||||
|
, NoProtect = (1 << 18)
|
||||||
, HBothAccess = HAccess|HAccessEW
|
, HBothAccess = HAccess|HAccessEW
|
||||||
, SouthWest = SouthBound|WestBound
|
, SouthWest = SouthBound|WestBound
|
||||||
, NorthEast = NorthBound|EastBound
|
, NorthEast = NorthBound|EastBound
|
||||||
|
@ -204,6 +205,8 @@ namespace Anabatic {
|
||||||
virtual bool _do_xG ();
|
virtual bool _do_xG ();
|
||||||
virtual bool _do_2G ();
|
virtual bool _do_2G ();
|
||||||
virtual bool _do_xG_1Pad ();
|
virtual bool _do_xG_1Pad ();
|
||||||
|
virtual bool _do_1G_1PinM1 ();
|
||||||
|
virtual bool _do_2G_1PinM1 ();
|
||||||
virtual bool _do_1G_1PinM2 ();
|
virtual bool _do_1G_1PinM2 ();
|
||||||
virtual bool _do_xG_1PinM2 ();
|
virtual bool _do_xG_1PinM2 ();
|
||||||
virtual bool _do_1G_1PinM3 ();
|
virtual bool _do_1G_1PinM3 ();
|
||||||
|
@ -298,6 +301,8 @@ namespace Anabatic {
|
||||||
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
|
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
|
||||||
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
|
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
|
||||||
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
|
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
|
||||||
|
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
||||||
|
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 )
|
||||||
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
|
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
|
||||||
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
|
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
|
||||||
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
|
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace Anabatic {
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
// Class : "NetBuilderHV".
|
// Class : "NetBuilderHV".
|
||||||
|
|
||||||
|
|
||||||
class NetBuilderHV : public NetBuilder {
|
class NetBuilderHV : public NetBuilder {
|
||||||
public:
|
public:
|
||||||
NetBuilderHV ();
|
NetBuilderHV ();
|
||||||
|
@ -38,6 +39,8 @@ namespace Anabatic {
|
||||||
virtual bool _do_2G ();
|
virtual bool _do_2G ();
|
||||||
virtual bool _do_2G_1M1 ();
|
virtual bool _do_2G_1M1 ();
|
||||||
virtual bool _do_xG_1Pad ();
|
virtual bool _do_xG_1Pad ();
|
||||||
|
virtual bool _do_1G_1PinM1 ();
|
||||||
|
virtual bool _do_2G_1PinM1 ();
|
||||||
virtual bool _do_1G_1PinM2 ();
|
virtual bool _do_1G_1PinM2 ();
|
||||||
virtual bool _do_xG_1PinM2 ();
|
virtual bool _do_xG_1PinM2 ();
|
||||||
virtual bool _do_1G_1PinM3 ();
|
virtual bool _do_1G_1PinM3 ();
|
||||||
|
|
|
@ -8,7 +8,8 @@ parametersTable = \
|
||||||
, ('etesian.routingDriven' , TypeBool , False )
|
, ('etesian.routingDriven' , TypeBool , False )
|
||||||
, ('etesian.feedNames' , TypeString , 'tie_x0,rowend_x0')
|
, ('etesian.feedNames' , TypeString , 'tie_x0,rowend_x0')
|
||||||
, ('etesian.cell.zero' , TypeString , 'zero_x0' )
|
, ('etesian.cell.zero' , TypeString , 'zero_x0' )
|
||||||
, ('etesian.cell.one' , TypeString , 'one_x0' )
|
, ('etesian.cell.one' , TypeString , 'one_x0' )
|
||||||
|
, ('etesian.bloat' , TypeString , 'default' )
|
||||||
|
|
||||||
, ("etesian.effort" , TypeEnumerate , 2
|
, ("etesian.effort" , TypeEnumerate , 2
|
||||||
, { 'values':( ("Fast" , 1)
|
, { 'values':( ("Fast" , 1)
|
||||||
|
|
|
@ -41,6 +41,8 @@ parametersTable = \
|
||||||
)
|
)
|
||||||
, ("katana.hTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
|
, ("katana.hTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
|
||||||
, ("katana.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
|
, ("katana.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
|
||||||
|
, ("katana.termSatReservedLocal" ,TypeInt ,8 )
|
||||||
|
, ("katana.termSatThreshold" ,TypeInt ,9 )
|
||||||
, ("katana.eventsLimit" ,TypeInt ,4000002 )
|
, ("katana.eventsLimit" ,TypeInt ,4000002 )
|
||||||
, ("katana.ripupCost" ,TypeInt ,3 , { 'min':0 } )
|
, ("katana.ripupCost" ,TypeInt ,3 , { 'min':0 } )
|
||||||
, ("katana.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } )
|
, ("katana.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } )
|
||||||
|
|
|
@ -31,10 +31,21 @@ parametersTable = \
|
||||||
, ("anabatic.edgeHInc" ,TypeDouble ,1.0 )
|
, ("anabatic.edgeHInc" ,TypeDouble ,1.0 )
|
||||||
, ("anabatic.edgeHScaling" ,TypeDouble ,1.0 )
|
, ("anabatic.edgeHScaling" ,TypeDouble ,1.0 )
|
||||||
, ("anabatic.globalIterations" ,TypeInt ,20 , { 'min':1, 'max':100 } )
|
, ("anabatic.globalIterations" ,TypeInt ,20 , { 'min':1, 'max':100 } )
|
||||||
|
, ("anabatic.saturateRatio" ,TypePercentage,80 )
|
||||||
, ("anabatic.gcell.displayMode" ,TypeEnumerate ,1
|
, ("anabatic.gcell.displayMode" ,TypeEnumerate ,1
|
||||||
, { 'values':( ("Boundary" , 1)
|
, { 'values':( ("Boundary" , 1)
|
||||||
, ("Density" , 2) ) }
|
, ("Density" , 2) ) }
|
||||||
)
|
)
|
||||||
|
, ("katana.hTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
|
||||||
|
, ("katana.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':20 } )
|
||||||
|
, ("katana.termSatReservedLocal" ,TypeInt ,8 )
|
||||||
|
, ("katana.termSatThreshold" ,TypeInt ,9 )
|
||||||
|
, ("katana.eventsLimit" ,TypeInt ,4000002 )
|
||||||
|
, ("katana.ripupCost" ,TypeInt ,3 , { 'min':0 } )
|
||||||
|
, ("katana.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } )
|
||||||
|
, ("katana.localRipupLimit" ,TypeInt ,9 , { 'min':1 } )
|
||||||
|
, ("katana.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
|
||||||
|
, ("katana.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,6 +82,7 @@ routingGaugesTable['msxlib-2M'] = \
|
||||||
# ( METAL_PIN, xy_common_pitch, slice_height, slice_step )
|
# ( METAL_PIN, xy_common_pitch, slice_height, slice_step )
|
||||||
|
|
||||||
cellGaugesTable = {}
|
cellGaugesTable = {}
|
||||||
cellGaugesTable['msxlib' ] = ('metal2', l(10), l(100), l(10))
|
cellGaugesTable['msxlib' ] = ('metal2', l(10), l(100), l( 10))
|
||||||
cellGaugesTable['msxlib4'] = ('metal2', l(10), l(100), l(10))
|
cellGaugesTable['msxlib4'] = ('metal2', l(10), l(100), l( 10))
|
||||||
|
cellGaugesTable['phlib80'] = ('metal2', l(10), l(312), l(246))
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ allianceConfig = \
|
||||||
, ( 'GROUND' , 'vss')
|
, ( 'GROUND' , 'vss')
|
||||||
, ( 'CLOCK' , '^ck.*')
|
, ( 'CLOCK' , '^ck.*')
|
||||||
, ( 'BLOCKAGE' , '^blockage[Nn]et*')
|
, ( 'BLOCKAGE' , '^blockage[Nn]et*')
|
||||||
, ( 'PAD' , '.*_mpx$')
|
, ( 'PAD' , '.*_sp$')
|
||||||
# The following are only read by the Alliance tool wrappers.
|
# The following are only read by the Alliance tool wrappers.
|
||||||
, ( 'ALLIANCE_TOP' , allianceTop)
|
, ( 'ALLIANCE_TOP' , allianceTop)
|
||||||
, ( 'MBK_TARGET_LIB' , cellsTop+'/msxlib')
|
, ( 'MBK_TARGET_LIB' , cellsTop+'/msxlib')
|
||||||
|
|
|
@ -3,8 +3,3 @@
|
||||||
import helpers
|
import helpers
|
||||||
|
|
||||||
execfile( helpers.sysConfDir+'/common/etesian.conf' )
|
execfile( helpers.sysConfDir+'/common/etesian.conf' )
|
||||||
|
|
||||||
parametersTable = \
|
|
||||||
( ('etesian.bloat' , TypeString , "nsxlib" )
|
|
||||||
,
|
|
||||||
)
|
|
||||||
|
|
|
@ -8,36 +8,45 @@ execfile( helpers.sysConfDir+'/common/kite.conf' )
|
||||||
|
|
||||||
|
|
||||||
parametersTable = \
|
parametersTable = \
|
||||||
( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 )
|
( ('lefImport.minTerminalWidth' , TypeDouble , 0.0 )
|
||||||
, ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters.
|
, ("katabatic.globalLengthThreshold", TypeInt , 1450 ) # Katabatic parameters.
|
||||||
, ("katabatic.saturateRatio" ,TypePercentage,80 )
|
, ("katabatic.saturateRatio" , TypePercentage, 80 )
|
||||||
, ("katabatic.saturateRp" ,TypeInt ,8 )
|
, ("katabatic.saturateRp" , TypeInt , 8 )
|
||||||
, ('katabatic.topRoutingLayer' ,TypeString , 'METAL3')
|
, ('katabatic.topRoutingLayer' , TypeString , 'METAL3' )
|
||||||
# Kite parameters.
|
# Kite parameters.
|
||||||
, ("kite.hTracksReservedLocal" ,TypeInt ,4 , { 'min':0, 'max':18 } )
|
, ("kite.hTracksReservedLocal" , TypeInt , 4 , { 'min':0, 'max':18 } )
|
||||||
, ("kite.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':18 } )
|
, ("kite.vTracksReservedLocal" , TypeInt , 3 , { 'min':0, 'max':18 } )
|
||||||
, ("kite.eventsLimit" ,TypeInt ,4000002 )
|
, ("kite.eventsLimit" , TypeInt , 4000002 )
|
||||||
, ("kite.ripupCost" ,TypeInt ,3 , { 'min':0 } )
|
, ("kite.ripupCost" , TypeInt , 3 , { 'min':0 } )
|
||||||
, ("kite.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } )
|
, ("kite.strapRipupLimit" , TypeInt , 16 , { 'min':1 } )
|
||||||
, ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } )
|
, ("kite.localRipupLimit" , TypeInt , 9 , { 'min':1 } )
|
||||||
, ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
|
, ("kite.globalRipupLimit" , TypeInt , 5 , { 'min':1 } )
|
||||||
, ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
|
, ("kite.longGlobalRipupLimit" , TypeInt , 5 , { 'min':1 } )
|
||||||
# Anabatic parameters are temporarily hosted here.
|
# Anabatic parameters are temporarily hosted here.
|
||||||
, ('anabatic.topRoutingLayer' ,TypeString , 'METAL3')
|
, ('anabatic.topRoutingLayer' , TypeString , 'METAL3' )
|
||||||
, ("anabatic.routingGauge" ,TypeString ,'msxlib3')
|
, ("anabatic.routingGauge" , TypeString , 'msxlib3')
|
||||||
, ("anabatic.edgeLength" ,TypeInt ,48 )
|
, ("anabatic.edgeLength" , TypeInt , 48 )
|
||||||
, ("anabatic.edgeWidth" ,TypeInt ,8 )
|
, ("anabatic.edgeWidth" , TypeInt , 8 )
|
||||||
, ("anabatic.edgeCostH" ,TypeDouble ,19.0 )
|
, ("anabatic.edgeCostH" , TypeDouble , 19.0 )
|
||||||
, ("anabatic.edgeCostK" ,TypeDouble ,-60.0 )
|
, ("anabatic.edgeCostK" , TypeDouble , -60.0 )
|
||||||
, ("anabatic.edgeHInc" ,TypeDouble ,1.0 )
|
, ("anabatic.edgeHInc" , TypeDouble , 1.0 )
|
||||||
, ("anabatic.edgeHScaling" ,TypeDouble ,1.0 )
|
, ("anabatic.edgeHScaling" , TypeDouble , 1.0 )
|
||||||
, ("anabatic.globalIterations" ,TypeInt ,20 , { 'min':1, 'max':100 } )
|
, ("anabatic.globalIterations" , TypeInt , 20 , { 'min':1, 'max':100 } )
|
||||||
, ("anabatic.gcell.displayMode" ,TypeEnumerate ,1
|
, ("anabatic.gcell.displayMode" , TypeEnumerate , 1
|
||||||
, { 'values':( ("Boundary" , 1)
|
, { 'values':( ("Boundary" , 1)
|
||||||
, ("Density" , 2) ) }
|
, ("Density" , 2) ) }
|
||||||
)
|
)
|
||||||
, ("katana.hTracksReservedLocal" , TypeInt , 5 )
|
, ("katana.hTracksReservedLocal" , TypeInt , 5 )
|
||||||
, ("katana.vTracksReservedLocal" , TypeInt , 3 )
|
, ("katana.vTracksReservedLocal" , TypeInt , 3 )
|
||||||
|
, ("katana.termSatReservedLocal" , TypeInt , 5 )
|
||||||
|
, ("katana.termSatThreshold" , TypeInt , 11 )
|
||||||
|
, ("katana.eventsLimit" , TypeInt , 4000002 )
|
||||||
|
, ("katana.ripupCost" , TypeInt , 3 , { 'min':0 } )
|
||||||
|
, ("katana.strapRipupLimit" , TypeInt , 16 , { 'min':1 } )
|
||||||
|
, ("katana.localRipupLimit" , TypeInt , 9 , { 'min':1 } )
|
||||||
|
, ("katana.globalRipupLimit" , TypeInt , 5 , { 'min':1 } )
|
||||||
|
, ("katana.longGlobalRipupLimit" , TypeInt , 5 , { 'min':1 } )
|
||||||
|
, ('chip.padCoreSide' , TypeString , 'South' )
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,4 +92,5 @@ cellGaugesTable = {}
|
||||||
cellGaugesTable['msxlib' ] = ('metal2', l(10), l(100), l(10))
|
cellGaugesTable['msxlib' ] = ('metal2', l(10), l(100), l(10))
|
||||||
cellGaugesTable['msxlib4'] = ('metal2', l(10), l(100), l(10))
|
cellGaugesTable['msxlib4'] = ('metal2', l(10), l(100), l(10))
|
||||||
cellGaugesTable['msxlib3'] = ('metal2', l(10), l(100), l(10))
|
cellGaugesTable['msxlib3'] = ('metal2', l(10), l(100), l(10))
|
||||||
|
cellGaugesTable['phlib80'] = ('metal2', l( 1), l(312), l(246))
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from helpers import l, u, n
|
||||||
#
|
#
|
||||||
# Parameters for chip plugin.
|
# Parameters for chip plugin.
|
||||||
parametersTable = \
|
parametersTable = \
|
||||||
( ("chip.block.rails.count" , TypeInt , l(5 ) )
|
( ("chip.block.rails.count" , TypeInt , 5 )
|
||||||
, ("chip.block.rails.hWidth" , TypeInt , l(24) )
|
, ("chip.block.rails.hWidth" , TypeInt , l(24) )
|
||||||
, ("chip.block.rails.vWidth" , TypeInt , l(24) )
|
, ("chip.block.rails.vWidth" , TypeInt , l(24) )
|
||||||
, ("chip.block.rails.hSpacing" , TypeInt , l(12) )
|
, ("chip.block.rails.hSpacing" , TypeInt , l(12) )
|
||||||
|
|
|
@ -522,16 +522,17 @@ namespace {
|
||||||
|
|
||||||
if (layerInfo and net) {
|
if (layerInfo and net) {
|
||||||
net->setExternal( true );
|
net->setExternal( true );
|
||||||
/*pin =*/ Pin::create( net
|
Pin* pin = Pin::create( net
|
||||||
, pinName
|
, pinName
|
||||||
, accessDirection
|
, accessDirection
|
||||||
, Pin::PlacementStatus::PLACED
|
, Pin::PlacementStatus::PLACED
|
||||||
, layerInfo->getLayer()
|
, layerInfo->getLayer()
|
||||||
, XCON
|
, XCON
|
||||||
, YCON
|
, YCON
|
||||||
, WIDTH
|
, WIDTH
|
||||||
, HEIGHT
|
, HEIGHT
|
||||||
);
|
);
|
||||||
|
NetExternalComponents::setExternal( pin );
|
||||||
}
|
}
|
||||||
if (not net ) _printError( false, "Unknown net name <%s>." , fields[5] );
|
if (not net ) _printError( false, "Unknown net name <%s>." , fields[5] );
|
||||||
if (not layerInfo ) _printError( false, "Unknown layer name <%s>.", fields[6] );
|
if (not layerInfo ) _printError( false, "Unknown layer name <%s>.", fields[6] );
|
||||||
|
@ -687,18 +688,18 @@ namespace {
|
||||||
_printError ( false, "Unknown orientation (%s).", getString(orientName).c_str() );
|
_printError ( false, "Unknown orientation (%s).", getString(orientName).c_str() );
|
||||||
|
|
||||||
Instance* instance = _cell->getInstance ( instanceName );
|
Instance* instance = _cell->getInstance ( instanceName );
|
||||||
if ( instance ) {
|
if (instance) {
|
||||||
instance->setTransformation
|
instance->setTransformation
|
||||||
( getTransformation ( instance->getMasterCell()->getAbutmentBox()
|
( getTransformation( instance->getMasterCell()->getAbutmentBox()
|
||||||
, XINS
|
, XINS
|
||||||
, YINS
|
, YINS
|
||||||
, orient
|
, orient
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
instance->setPlacementStatus ( Instance::PlacementStatus::FIXED );
|
instance->setPlacementStatus( Instance::PlacementStatus::FIXED );
|
||||||
} else {
|
} else {
|
||||||
bool ignoreInstance = (getString(masterCellName).substr(0,7) == padreal);
|
bool ignoreInstance = _framework->isPad( _cell );
|
||||||
Catalog::State* instanceState = _framework->getCatalog()->getState ( masterCellName );
|
Catalog::State* instanceState = _framework->getCatalog()->getState( masterCellName );
|
||||||
if ( not ignoreInstance and ( not instanceState or (not instanceState->isFeed()) ) ) {
|
if ( not ignoreInstance and ( not instanceState or (not instanceState->isFeed()) ) ) {
|
||||||
_printError ( false
|
_printError ( false
|
||||||
, "No logical instance associated to physical instance %s."
|
, "No logical instance associated to physical instance %s."
|
||||||
|
@ -710,30 +711,30 @@ namespace {
|
||||||
// Load a cell that is not in the logical view. Only feedthrough Cell
|
// Load a cell that is not in the logical view. Only feedthrough Cell
|
||||||
// could be in that case.
|
// could be in that case.
|
||||||
tab++;
|
tab++;
|
||||||
Cell* masterCell = _framework->getCell ( getString(masterCellName)
|
Cell* masterCell = _framework->getCell( getString(masterCellName)
|
||||||
, Catalog::State::Views
|
, Catalog::State::Views
|
||||||
);
|
);
|
||||||
tab--;
|
tab--;
|
||||||
|
|
||||||
if ( !masterCell ) {
|
if (not masterCell) {
|
||||||
_printError ( "Unable to load model %s.", getString(masterCellName).c_str() );
|
_printError( "Unable to load model %s.", getString(masterCellName).c_str() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ignoreInstance = ignoreInstance and _cell->isTerminal();
|
ignoreInstance = ignoreInstance and _cell->isTerminal();
|
||||||
|
|
||||||
instance = Instance::create ( _cell
|
instance = Instance::create( _cell
|
||||||
, instanceName
|
, instanceName
|
||||||
, masterCell
|
, masterCell
|
||||||
, getTransformation ( masterCell->getAbutmentBox()
|
, getTransformation ( masterCell->getAbutmentBox()
|
||||||
, XINS
|
, XINS
|
||||||
, YINS
|
, YINS
|
||||||
, orient
|
, orient
|
||||||
)
|
)
|
||||||
, Instance::PlacementStatus::FIXED
|
, Instance::PlacementStatus::FIXED
|
||||||
, true // Checking of recursive calls
|
, true // Checking of recursive calls
|
||||||
);
|
);
|
||||||
_cell->setTerminal ( ignoreInstance );
|
_cell->setTerminal( ignoreInstance );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_cmos.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_cmos.py
|
||||||
#${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_c35b4.py
|
#${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_c35b4.py
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_phlib80.py
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlace.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlace.py
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipRoute.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipRoute.py
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/RSavePlugin.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/RSavePlugin.py
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/CoreToChip.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/CoreToChip.py
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/cmos.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/cmos.py
|
||||||
#${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/c35b4.py
|
#${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/c35b4.py
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/core2chip/phlib80.py
|
||||||
)
|
)
|
||||||
set ( pyPluginChip ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/__init__.py
|
set ( pyPluginChip ${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/__init__.py
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/Configuration.py
|
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/Configuration.py
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# This file is part of the Coriolis Software.
|
||||||
|
# Copyright (c) UPMC 2019-2018, All Rights Reserved
|
||||||
|
#
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
# | C O R I O L I S |
|
||||||
|
# | C u m u l u s - P y t h o n T o o l s |
|
||||||
|
# | |
|
||||||
|
# | Author : Jean-Paul CHAPUT |
|
||||||
|
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||||
|
# | =============================================================== |
|
||||||
|
# | Python : "./plugins/CoreToChip_phlib80.py" |
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import helpers
|
||||||
|
from helpers.io import ErrorMessage
|
||||||
|
from helpers.io import WarningMessage
|
||||||
|
import plugins
|
||||||
|
import core2chip.phlib80
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------
|
||||||
|
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||||
|
|
||||||
|
def unicornHook ( **kw ):
|
||||||
|
kw['beforeAction'] = 'placeAndRoute.stepByStep'
|
||||||
|
#kw['beforeAction'] = 'placeAndRoute.clockTree'
|
||||||
|
|
||||||
|
plugins.kwAddMenu ( 'placeAndRoute' , 'P&&R', **kw )
|
||||||
|
plugins.kwAddMenu ( 'placeAndRoute.core2chip', 'Core To Chip', **kw )
|
||||||
|
plugins.kwUnicornHook( 'placeAndRoute.core2chip.phlib80'
|
||||||
|
, 'Phenitec08 Symbolic CMOS I/O pads'
|
||||||
|
, 'Wrap a complete chip around a Core for Phenitec generic CMOS'
|
||||||
|
, sys.modules[__name__].__file__
|
||||||
|
, **kw
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def ScriptMain ( **kw ):
|
||||||
|
rvalue = True
|
||||||
|
try:
|
||||||
|
helpers.staticInitialization( quiet=True )
|
||||||
|
#helpers.setTraceLevel( 550 )
|
||||||
|
|
||||||
|
cell, editor = plugins.kwParseMain( **kw )
|
||||||
|
if not cell:
|
||||||
|
raise ErrorMessage( 1, 'CoreToChip_phlib80.ScriptMain(): No cell (core) loaded in the editor yet.' )
|
||||||
|
|
||||||
|
chip_phlib80 = core2chip.phlib80.phlib80( cell )
|
||||||
|
chip_phlib80.buildChip()
|
||||||
|
|
||||||
|
if editor: editor.setCell( chip_phlib80.chip )
|
||||||
|
|
||||||
|
except Exception, e:
|
||||||
|
helpers.io.catch( e )
|
||||||
|
rvalue = False
|
||||||
|
|
||||||
|
sys.stdout.flush()
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
|
return rvalue
|
|
@ -258,9 +258,6 @@ class Side ( object ):
|
||||||
def check ( self ):
|
def check ( self ):
|
||||||
self.validated = True
|
self.validated = True
|
||||||
if self.type == chip.North:
|
if self.type == chip.North:
|
||||||
#print DbU.getValueString(self.conf.coreSize.getWidth())
|
|
||||||
#print DbU.getValueString(self.conf.minCorona)
|
|
||||||
#print DbU.getValueString(self.conf.getIoPadHeight())
|
|
||||||
self.validated = self._check( self.conf.coreSize.getWidth()
|
self.validated = self._check( self.conf.coreSize.getWidth()
|
||||||
+ 2*self.conf.minCorona
|
+ 2*self.conf.minCorona
|
||||||
+ 2*self.conf.getIoPadHeight()
|
+ 2*self.conf.getIoPadHeight()
|
||||||
|
@ -1086,8 +1083,10 @@ class Corona ( object ):
|
||||||
rg = self.conf.gaugeConf.routingGauge
|
rg = self.conf.gaugeConf.routingGauge
|
||||||
hsegments = { }
|
hsegments = { }
|
||||||
vsegments = { }
|
vsegments = { }
|
||||||
|
|
||||||
for component in padNet.getExternalComponents():
|
for component in padNet.getExternalComponents():
|
||||||
if isinstance(component,Segment):
|
if isinstance(component,Segment) or isinstance(component,Contact):
|
||||||
|
|
||||||
bb = component.getBoundingBox()
|
bb = component.getBoundingBox()
|
||||||
padInstance.getTransformation().applyOn( bb )
|
padInstance.getTransformation().applyOn( bb )
|
||||||
if bb.intersect(innerBb):
|
if bb.intersect(innerBb):
|
||||||
|
@ -1136,6 +1135,16 @@ class Corona ( object ):
|
||||||
side.updateGap ( gapWidth )
|
side.updateGap ( gapWidth )
|
||||||
side.addCoreWire( CoreWire( self, chipIntNet, segment, bb, side.type, inPreferredDir, count ) )
|
side.addCoreWire( CoreWire( self, chipIntNet, segment, bb, side.type, inPreferredDir, count ) )
|
||||||
count += 1
|
count += 1
|
||||||
|
else:
|
||||||
|
if not chipIntNet.isGlobal():
|
||||||
|
raise ErrorMessage( 1, [ 'PadsCorona._createCoreWire(): In I/O pad "%s" (%s),'
|
||||||
|
% ( padInstance.getMasterCell().getName()
|
||||||
|
, padInstance.getName() )
|
||||||
|
, 'connector "%s" has no suitable segment for net "%s".'
|
||||||
|
% ( padNet.getName()
|
||||||
|
, chipIntNet.getName() )
|
||||||
|
] )
|
||||||
|
|
||||||
return count
|
return count
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,9 @@ class IoNet ( object ):
|
||||||
|
|
||||||
# Chip "external" net, connected to the pad I/O to the outside world.
|
# Chip "external" net, connected to the pad I/O to the outside world.
|
||||||
if not self.chipExtNet and (context & IoNet.DoExtNet):
|
if not self.chipExtNet and (context & IoNet.DoExtNet):
|
||||||
self.chipExtNet = Net.create( self.coreToChip.chip, self.padNetName )
|
self.chipExtNet = self.coreToChip.chip.getNet( self.padNetName )
|
||||||
|
if not self.chipExtNet:
|
||||||
|
self.chipExtNet = Net.create( self.coreToChip.chip, self.padNetName )
|
||||||
self.chipExtNet.setExternal ( True )
|
self.chipExtNet.setExternal ( True )
|
||||||
self.chipExtNet.setDirection( self.coreNet.getDirection() )
|
self.chipExtNet.setDirection( self.coreNet.getDirection() )
|
||||||
|
|
||||||
|
@ -190,6 +192,7 @@ class IoPad ( object ):
|
||||||
if len(self.nets) == 1:
|
if len(self.nets) == 1:
|
||||||
if self.nets[0].coreNet.getDirection() == Net.Direction.IN: self.direction = IoPad.IN
|
if self.nets[0].coreNet.getDirection() == Net.Direction.IN: self.direction = IoPad.IN
|
||||||
elif self.nets[0].coreNet.getDirection() == Net.Direction.OUT: self.direction = IoPad.OUT
|
elif self.nets[0].coreNet.getDirection() == Net.Direction.OUT: self.direction = IoPad.OUT
|
||||||
|
elif self.nets[0].coreNet.getName() == 'scout': self.direction = IoPad.OUT
|
||||||
else:
|
else:
|
||||||
raise ErrorMessage( 1, 'IoPad.addNet(): Unsupported direction %d (%s) for core net "%s" in I/O pad \"%s\".' \
|
raise ErrorMessage( 1, 'IoPad.addNet(): Unsupported direction %d (%s) for core net "%s" in I/O pad \"%s\".' \
|
||||||
% ( self.nets[0].coreNet.getDirection()
|
% ( self.nets[0].coreNet.getDirection()
|
||||||
|
@ -339,7 +342,9 @@ class CoreToChip ( object ):
|
||||||
for ringNetSpec in self.ringNetNames:
|
for ringNetSpec in self.ringNetNames:
|
||||||
if isinstance(ringNetSpec,tuple): ringNetName = ringNetSpec[0]
|
if isinstance(ringNetSpec,tuple): ringNetName = ringNetSpec[0]
|
||||||
else: ringNetName = ringNetSpec
|
else: ringNetName = ringNetSpec
|
||||||
ringNet = Net.create( self.chip, ringNetName )
|
ringNet = self.chip.getNet( ringNetName )
|
||||||
|
if not ringNet:
|
||||||
|
ringNet = Net.create( self.chip, ringNetName )
|
||||||
ringNet.setType ( self.getNetType(ringNetName) )
|
ringNet.setType ( self.getNetType(ringNetName) )
|
||||||
ringNet.setGlobal( self.isGlobal (ringNetName) )
|
ringNet.setGlobal( self.isGlobal (ringNetName) )
|
||||||
return
|
return
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# This file is part of the Coriolis Software.
|
||||||
|
# Copyright (c) UPMC 2019-2018, All Rights Reserved
|
||||||
|
#
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
# | C O R I O L I S |
|
||||||
|
# | C u m u l u s - P y t h o n T o o l s |
|
||||||
|
# | |
|
||||||
|
# | Author : Jean-Paul CHAPUT |
|
||||||
|
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||||
|
# | =============================================================== |
|
||||||
|
# | Python : "./plugins/core2chip/cmos.py" |
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
import re
|
||||||
|
from Hurricane import DbU
|
||||||
|
from Hurricane import DataBase
|
||||||
|
from Hurricane import UpdateSession
|
||||||
|
from Hurricane import Breakpoint
|
||||||
|
from Hurricane import Transformation
|
||||||
|
from Hurricane import Instance
|
||||||
|
from Hurricane import Net
|
||||||
|
import Viewer
|
||||||
|
from CRL import Catalog
|
||||||
|
from CRL import AllianceFramework
|
||||||
|
from helpers.io import ErrorMessage
|
||||||
|
from core2chip.CoreToChip import IoPad
|
||||||
|
from core2chip.CoreToChip import CoreToChip
|
||||||
|
|
||||||
|
|
||||||
|
class cmos ( CoreToChip ):
|
||||||
|
|
||||||
|
def __init__ ( self, core ):
|
||||||
|
CoreToChip.__init__ ( self, core )
|
||||||
|
self.ringNetNames = [ 'vsse', 'vssi', 'vdde', 'vddi', ('cki', 'ck') ]
|
||||||
|
self.ioPadInfos = { IoPad.IN : CoreToChip.IoPadInfo( 'pi_px' , 'pad', ['t',] )
|
||||||
|
, IoPad.OUT : CoreToChip.IoPadInfo( 'po_px' , 'pad', ['i',] )
|
||||||
|
, IoPad.TRI_OUT : CoreToChip.IoPadInfo( 'pot_px' , 'pad', ['i', 'b' ] )
|
||||||
|
, IoPad.BIDIR : CoreToChip.IoPadInfo( 'piot_px', 'pad', ['i', 't', 'b' ] )
|
||||||
|
}
|
||||||
|
self._getPadLib()
|
||||||
|
return
|
||||||
|
|
||||||
|
def _getPadLib ( self ):
|
||||||
|
self.padLib = AllianceFramework.get().getLibrary( "pxlib" )
|
||||||
|
|
||||||
|
if not self.padLib:
|
||||||
|
message = [ 'CoreToChip.cmos._getPadLib(): Unable to find Alliance "pxlib" library' ]
|
||||||
|
raise ErrorMessage( 1, message )
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def getNetType ( self, netName ):
|
||||||
|
if netName.startswith('vss'): return Net.Type.GROUND
|
||||||
|
if netName.startswith('vdd'): return Net.Type.POWER
|
||||||
|
if netName in ('cki', 'ck'): return Net.Type.CLOCK
|
||||||
|
return Net.Type.LOGICAL
|
||||||
|
|
||||||
|
def isGlobal ( self, netName ):
|
||||||
|
if netName in self.ringNetNames: return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getCell ( self, masterCellName ):
|
||||||
|
#cell = self.padLib.getCell( masterCellName )
|
||||||
|
cell = AllianceFramework.get().getCell( masterCellName, Catalog.State.Views )
|
||||||
|
if not cell:
|
||||||
|
raise ErrorMessage( 1, 'cmos.getCell(): I/O pad library "%s" does not contain cell named "%s"' \
|
||||||
|
% (self.padLib.getName(),masterCellName) )
|
||||||
|
return cell
|
||||||
|
|
||||||
|
def _buildGroundPads ( self, ioNet ):
|
||||||
|
ioNet.buildNets()
|
||||||
|
vssi = self.chip.getNet( 'vssi' )
|
||||||
|
vssi.setExternal( True )
|
||||||
|
vssi.setGlobal ( True )
|
||||||
|
vssi.setType ( Net.Type.GROUND )
|
||||||
|
vssi.merge( ioNet.chipIntNet )
|
||||||
|
ioNet.chipIntNet = vssi
|
||||||
|
|
||||||
|
vsse = self.chip.getNet( 'vsse' )
|
||||||
|
vsse.setExternal( True )
|
||||||
|
vsse.setGlobal ( True )
|
||||||
|
vsse.setType ( Net.Type.GROUND )
|
||||||
|
vsse.merge( ioNet.chipExtNet )
|
||||||
|
ioNet.chipExtNet = vsse
|
||||||
|
|
||||||
|
pads = []
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + 'ick_%d' % self.groundPadCount
|
||||||
|
, self.getCell('pvssick_px') ) )
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + 'eck_%d' % self.groundPadCount
|
||||||
|
, self.getCell('pvsseck_px') ) )
|
||||||
|
|
||||||
|
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vssi' )
|
||||||
|
CoreToChip._connect( pads[1], ioNet.chipExtNet, 'vsse' )
|
||||||
|
|
||||||
|
for pad in pads: self._connectRing( pad )
|
||||||
|
self.groundPadCount += 1
|
||||||
|
self.chipPads += pads
|
||||||
|
return
|
||||||
|
|
||||||
|
def _buildPowerPads ( self, ioNet ):
|
||||||
|
ioNet.buildNets()
|
||||||
|
vddi = self.chip.getNet( 'vddi' )
|
||||||
|
vddi.setExternal( True )
|
||||||
|
vddi.setGlobal ( True )
|
||||||
|
vddi.setType ( Net.Type.POWER )
|
||||||
|
vddi.merge( ioNet.chipIntNet )
|
||||||
|
ioNet.chipIntNet = vddi
|
||||||
|
|
||||||
|
vdde = self.chip.getNet( 'vdde' )
|
||||||
|
vdde.setExternal( True )
|
||||||
|
vdde.setGlobal ( True )
|
||||||
|
vdde.setType ( Net.Type.POWER )
|
||||||
|
vdde.merge( ioNet.chipExtNet )
|
||||||
|
ioNet.chipExtNet = vdde
|
||||||
|
|
||||||
|
pads = [ ]
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + 'ick_%d' % self.powerPadCount
|
||||||
|
, self.getCell('pvddick_px') ) )
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + 'eck_%d' % self.powerPadCount
|
||||||
|
, self.getCell('pvddeck_px') ) )
|
||||||
|
|
||||||
|
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vddi' )
|
||||||
|
CoreToChip._connect( pads[1], ioNet.chipExtNet, 'vdde' )
|
||||||
|
|
||||||
|
for pad in pads: self._connectRing( pad )
|
||||||
|
self.powerPadCount += 1
|
||||||
|
self.chipPads += pads
|
||||||
|
return
|
||||||
|
|
||||||
|
def _buildClockPads ( self, ioNet ):
|
||||||
|
ioNet.buildNets()
|
||||||
|
pads = [ ]
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + '_%d' % self.clockPadCount
|
||||||
|
, self.getCell('pck_px') ) )
|
||||||
|
|
||||||
|
CoreToChip._connect( pads[0], ioNet.chipExtNet, 'pad' )
|
||||||
|
|
||||||
|
for pad in pads: self._connectRing( pad )
|
||||||
|
self.clockPadCount += 1
|
||||||
|
self.chipPads += pads
|
||||||
|
|
||||||
|
p = re.compile( r'pv[ds]{2}[ei]ck_px' )
|
||||||
|
for pad in self.chipPads:
|
||||||
|
if p.match( pad.getMasterCell().getName() ):
|
||||||
|
CoreToChip._connect( pad, ioNet.chipIntNet, 'cko' )
|
||||||
|
return
|
|
@ -0,0 +1,133 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# This file is part of the Coriolis Software.
|
||||||
|
# Copyright (c) UPMC 2019-2018, All Rights Reserved
|
||||||
|
#
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
# | C O R I O L I S |
|
||||||
|
# | C u m u l u s - P y t h o n T o o l s |
|
||||||
|
# | |
|
||||||
|
# | Author : Jean-Paul CHAPUT |
|
||||||
|
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||||
|
# | =============================================================== |
|
||||||
|
# | Python : "./plugins/core2chip/phlib80.py" |
|
||||||
|
# +-----------------------------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
import re
|
||||||
|
from Hurricane import DbU
|
||||||
|
from Hurricane import DataBase
|
||||||
|
from Hurricane import UpdateSession
|
||||||
|
from Hurricane import Breakpoint
|
||||||
|
from Hurricane import Transformation
|
||||||
|
from Hurricane import Instance
|
||||||
|
from Hurricane import Net
|
||||||
|
import Viewer
|
||||||
|
from CRL import Catalog
|
||||||
|
from CRL import AllianceFramework
|
||||||
|
from helpers.io import ErrorMessage
|
||||||
|
from core2chip.CoreToChip import IoPad
|
||||||
|
from core2chip.CoreToChip import CoreToChip
|
||||||
|
|
||||||
|
|
||||||
|
class phlib80 ( CoreToChip ):
|
||||||
|
|
||||||
|
def __init__ ( self, core ):
|
||||||
|
CoreToChip.__init__ ( self, core )
|
||||||
|
self.ringNetNames = [ 'vss', 'vss', ('cki', 'ck') ]
|
||||||
|
self.ioPadInfos = { IoPad.IN : CoreToChip.IoPadInfo( 'pi_sp' , 'pad', ['t',] )
|
||||||
|
, IoPad.OUT : CoreToChip.IoPadInfo( 'po_sp' , 'pad', ['i',] )
|
||||||
|
#, IoPad.TRI_OUT : CoreToChip.IoPadInfo( 'pot_sp' , 'pad', ['i', 'b' ] )
|
||||||
|
#, IoPad.BIDIR : CoreToChip.IoPadInfo( 'piot_sp', 'pad', ['i', 't', 'b' ] )
|
||||||
|
}
|
||||||
|
self._getPadLib()
|
||||||
|
return
|
||||||
|
|
||||||
|
def _getPadLib ( self ):
|
||||||
|
self.padLib = AllianceFramework.get().getLibrary( 'phlib80' )
|
||||||
|
|
||||||
|
if not self.padLib:
|
||||||
|
message = [ 'CoreToChip.phlib80._getPadLib(): Unable to find Alliance "phlib80" library' ]
|
||||||
|
raise ErrorMessage( 1, message )
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def getNetType ( self, netName ):
|
||||||
|
if netName.startswith('vss'): return Net.Type.GROUND
|
||||||
|
if netName.startswith('vdd'): return Net.Type.POWER
|
||||||
|
if netName in ('cko', 'ck'): return Net.Type.CLOCK
|
||||||
|
return Net.Type.LOGICAL
|
||||||
|
|
||||||
|
def isGlobal ( self, netName ):
|
||||||
|
if netName in self.ringNetNames: return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getCell ( self, masterCellName ):
|
||||||
|
#cell = self.padLib.getCell( masterCellName )
|
||||||
|
cell = AllianceFramework.get().getCell( masterCellName, Catalog.State.Views )
|
||||||
|
if not cell:
|
||||||
|
raise ErrorMessage( 1, 'cmos.getCell(): I/O pad library "%s" does not contain cell named "%s"' \
|
||||||
|
% (self.padLib.getName(),masterCellName) )
|
||||||
|
return cell
|
||||||
|
|
||||||
|
def _buildGroundPads ( self, ioNet ):
|
||||||
|
ioNet.buildNets()
|
||||||
|
vss = self.chip.getNet( 'vss' )
|
||||||
|
vss.setExternal( True )
|
||||||
|
vss.setGlobal ( True )
|
||||||
|
vss.setType ( Net.Type.GROUND )
|
||||||
|
vss.merge( ioNet.chipIntNet )
|
||||||
|
ioNet.chipIntNet = vss
|
||||||
|
|
||||||
|
pads = []
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + 'ck_%d' % self.groundPadCount
|
||||||
|
, self.getCell('pvssck2_sp') ) )
|
||||||
|
|
||||||
|
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vss' )
|
||||||
|
|
||||||
|
for pad in pads: self._connectRing( pad )
|
||||||
|
self.groundPadCount += 1
|
||||||
|
self.chipPads += pads
|
||||||
|
return
|
||||||
|
|
||||||
|
def _buildPowerPads ( self, ioNet ):
|
||||||
|
ioNet.buildNets()
|
||||||
|
vdd = self.chip.getNet( 'vdd' )
|
||||||
|
vdd.setExternal( True )
|
||||||
|
vdd.setGlobal ( True )
|
||||||
|
vdd.setType ( Net.Type.POWER )
|
||||||
|
vdd.merge( ioNet.chipIntNet )
|
||||||
|
ioNet.chipIntNet = vdd
|
||||||
|
|
||||||
|
pads = [ ]
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + 'ck_%d' % self.powerPadCount
|
||||||
|
, self.getCell('pvddck2_sp') ) )
|
||||||
|
|
||||||
|
CoreToChip._connect( pads[0], ioNet.chipIntNet, 'vdd' )
|
||||||
|
|
||||||
|
for pad in pads: self._connectRing( pad )
|
||||||
|
self.powerPadCount += 1
|
||||||
|
self.chipPads += pads
|
||||||
|
return
|
||||||
|
|
||||||
|
def _buildClockPads ( self, ioNet ):
|
||||||
|
ioNet.buildNets()
|
||||||
|
pads = [ ]
|
||||||
|
pads.append( Instance.create( self.chip
|
||||||
|
, 'p_' + ioNet.padInstanceName + '_%d' % self.clockPadCount
|
||||||
|
, self.getCell('pck_sp') ) )
|
||||||
|
|
||||||
|
CoreToChip._connect( pads[0], ioNet.chipExtNet, 'pad' )
|
||||||
|
|
||||||
|
for pad in pads: self._connectRing( pad )
|
||||||
|
self.clockPadCount += 1
|
||||||
|
self.chipPads += pads
|
||||||
|
|
||||||
|
p = re.compile( r'pv[ds]{2}ck2_sp' )
|
||||||
|
for pad in self.chipPads:
|
||||||
|
if p.match( pad.getMasterCell().getName() ):
|
||||||
|
CoreToChip._connect( pad, ioNet.chipIntNet, 'cko' )
|
||||||
|
return
|
|
@ -88,6 +88,39 @@ namespace Etesian {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Bloat3Metals::Bloat3Metals ()
|
||||||
|
: BloatCell("3metals")
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
Bloat3Metals::~Bloat3Metals ()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
DbU::Unit Bloat3Metals::getDx ( const Cell* cell, const EtesianEngine* etesian ) const
|
||||||
|
{
|
||||||
|
int terminals = 0;
|
||||||
|
for ( Net* net : cell->getNets() ) {
|
||||||
|
if (net->isExternal() and not net->isPower()) ++terminals;
|
||||||
|
}
|
||||||
|
|
||||||
|
Box ab ( cell->getAbutmentBox() );
|
||||||
|
DbU::Unit vpitch = etesian->getVerticalPitch();;
|
||||||
|
int xsize = (ab.getWidth() + vpitch - 1) / vpitch;
|
||||||
|
|
||||||
|
// float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch);
|
||||||
|
// if (termRatio > 0.5) {
|
||||||
|
// return vpitch*6;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (xsize < 4) return vpitch*4;
|
||||||
|
if (xsize < 6) return vpitch*2;
|
||||||
|
if (xsize < 8) return vpitch*1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BloatCells::select ( std::string profile )
|
bool BloatCells::select ( std::string profile )
|
||||||
{
|
{
|
||||||
BloatKey key ( profile );
|
BloatKey key ( profile );
|
||||||
|
|
|
@ -82,6 +82,14 @@ namespace Etesian {
|
||||||
virtual ~BloatNsxlib ();
|
virtual ~BloatNsxlib ();
|
||||||
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const;
|
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Bloat3Metals : public BloatCell {
|
||||||
|
public:
|
||||||
|
Bloat3Metals ();
|
||||||
|
virtual ~Bloat3Metals ();
|
||||||
|
virtual DbU::Unit getDx ( const Cell*, const EtesianEngine* ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class BloatCells {
|
class BloatCells {
|
||||||
|
@ -108,6 +116,7 @@ namespace Etesian {
|
||||||
{
|
{
|
||||||
_bloatCells.insert( new BloatDisabled() );
|
_bloatCells.insert( new BloatDisabled() );
|
||||||
_bloatCells.insert( new BloatNsxlib () );
|
_bloatCells.insert( new BloatNsxlib () );
|
||||||
|
_bloatCells.insert( new Bloat3Metals () );
|
||||||
select( "disabled" );
|
select( "disabled" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ namespace Katana {
|
||||||
, _postEventCb ()
|
, _postEventCb ()
|
||||||
, _hTracksReservedLocal(Cfg::getParamInt ("katana.hTracksReservedLocal", 3)->asInt())
|
, _hTracksReservedLocal(Cfg::getParamInt ("katana.hTracksReservedLocal", 3)->asInt())
|
||||||
, _vTracksReservedLocal(Cfg::getParamInt ("katana.vTracksReservedLocal", 3)->asInt())
|
, _vTracksReservedLocal(Cfg::getParamInt ("katana.vTracksReservedLocal", 3)->asInt())
|
||||||
|
, _termSatReservedLocal(Cfg::getParamInt ("katana.termSatReservedLocal", 9)->asInt())
|
||||||
|
, _termSatThreshold (Cfg::getParamInt ("katana.termSatThreshold" , 8)->asInt())
|
||||||
, _ripupLimits ()
|
, _ripupLimits ()
|
||||||
, _ripupCost (Cfg::getParamInt ("katana.ripupCost" , 3)->asInt())
|
, _ripupCost (Cfg::getParamInt ("katana.ripupCost" , 3)->asInt())
|
||||||
, _eventsLimit (Cfg::getParamInt ("katana.eventsLimit" ,4000000)->asInt())
|
, _eventsLimit (Cfg::getParamInt ("katana.eventsLimit" ,4000000)->asInt())
|
||||||
|
@ -80,6 +82,8 @@ namespace Katana {
|
||||||
, _postEventCb (other._postEventCb)
|
, _postEventCb (other._postEventCb)
|
||||||
, _hTracksReservedLocal(other._hTracksReservedLocal)
|
, _hTracksReservedLocal(other._hTracksReservedLocal)
|
||||||
, _vTracksReservedLocal(other._vTracksReservedLocal)
|
, _vTracksReservedLocal(other._vTracksReservedLocal)
|
||||||
|
, _termSatReservedLocal(other._termSatReservedLocal)
|
||||||
|
, _termSatThreshold (other._termSatThreshold)
|
||||||
, _ripupLimits ()
|
, _ripupLimits ()
|
||||||
, _ripupCost (other._ripupCost)
|
, _ripupCost (other._ripupCost)
|
||||||
, _eventsLimit (other._eventsLimit)
|
, _eventsLimit (other._eventsLimit)
|
||||||
|
@ -148,13 +152,16 @@ namespace Katana {
|
||||||
if (not cmess1.enabled()) return;
|
if (not cmess1.enabled()) return;
|
||||||
|
|
||||||
cout << " o Configuration of ToolEngine<Katana> for Cell <" << cell->getName() << ">" << endl;
|
cout << " o Configuration of ToolEngine<Katana> for Cell <" << cell->getName() << ">" << endl;
|
||||||
cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl;
|
cout << Dots::asDouble(" - GCell saturate ratio (LA)" ,getSaturateRatio()) << endl;
|
||||||
cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << endl;
|
cout << Dots::asUInt (" - Edge max H reserved local" ,_hTracksReservedLocal) << endl;
|
||||||
cout << Dots::asULong(" - Events limit (iterations)" ,_eventsLimit) << endl;
|
cout << Dots::asUInt (" - Edge max V reserved local" ,_vTracksReservedLocal) << endl;
|
||||||
cout << Dots::asUInt (" - Ripup limit, straps & unbreakables" ,_ripupLimits[StrapRipupLimit]) << endl;
|
cout << Dots::asUInt (" - Terminal saturated edge capacity" ,_termSatReservedLocal) << endl;
|
||||||
cout << Dots::asUInt (" - Ripup limit, locals" ,_ripupLimits[LocalRipupLimit]) << endl;
|
cout << Dots::asUInt (" - Terminal saturated GCell threshold" ,_termSatThreshold) << endl;
|
||||||
cout << Dots::asUInt (" - Ripup limit, globals" ,_ripupLimits[GlobalRipupLimit]) << endl;
|
cout << Dots::asULong (" - Events limit (iterations)" ,_eventsLimit) << endl;
|
||||||
cout << Dots::asUInt (" - Ripup limit, long globals" ,_ripupLimits[LongGlobalRipupLimit]) << endl;
|
cout << Dots::asUInt (" - Ripup limit, straps & unbreakables" ,_ripupLimits[StrapRipupLimit]) << endl;
|
||||||
|
cout << Dots::asUInt (" - Ripup limit, locals" ,_ripupLimits[LocalRipupLimit]) << endl;
|
||||||
|
cout << Dots::asUInt (" - Ripup limit, globals" ,_ripupLimits[GlobalRipupLimit]) << endl;
|
||||||
|
cout << Dots::asUInt (" - Ripup limit, long globals" ,_ripupLimits[LongGlobalRipupLimit]) << endl;
|
||||||
|
|
||||||
Super::print ( cell );
|
Super::print ( cell );
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,13 @@ namespace Katana {
|
||||||
printMeasures( "Anabatic Grid" );
|
printMeasures( "Anabatic Grid" );
|
||||||
|
|
||||||
setupNetDatas();
|
setupNetDatas();
|
||||||
|
computeEdgeCapacities( getHTracksReservedLocal()
|
||||||
|
, getVTracksReservedLocal()
|
||||||
|
, getTermSatThreshold()
|
||||||
|
, getTermSatReservedLocal()
|
||||||
|
);
|
||||||
|
|
||||||
|
#if UNIFORM_EDGE_CAPACITY
|
||||||
for ( GCell* gcell : getGCells() ) {
|
for ( GCell* gcell : getGCells() ) {
|
||||||
if (not gcell->isMatrix()) continue;
|
if (not gcell->isMatrix()) continue;
|
||||||
|
|
||||||
|
@ -237,6 +243,7 @@ namespace Katana {
|
||||||
else edge->reserveCapacity( getVTracksReservedLocal() );
|
else edge->reserveCapacity( getVTracksReservedLocal() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -480,19 +480,28 @@ namespace Katana {
|
||||||
|
|
||||||
Segment* segment = element->getSegment();
|
Segment* segment = element->getSegment();
|
||||||
Flags side = Flags::EastSide;
|
Flags side = Flags::EastSide;
|
||||||
DbU::Unit axis = segment->getY();
|
DbU::Unit axis = track->getAxis();
|
||||||
|
Point source = segment->getSourcePosition();
|
||||||
|
Point target = segment->getTargetPosition();
|
||||||
|
|
||||||
if (track->getDirection() == Flags::Vertical) {
|
if (track->getDirection() == Flags::Vertical) {
|
||||||
side = Flags::NorthSide;
|
side = Flags::NorthSide;
|
||||||
axis = segment->getX();
|
source.setX( axis );
|
||||||
|
target.setX( axis );
|
||||||
|
} else {
|
||||||
|
source.setY( axis );
|
||||||
|
target.setY( axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
int elementCapacity = 1;
|
int elementCapacity = 1;
|
||||||
cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl;
|
cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl;
|
||||||
|
|
||||||
GCellsUnder gcells = getGCellsUnder( segment );
|
GCellsUnder gcells = getGCellsUnder( source, target );
|
||||||
if (not gcells->empty()) {
|
if (not gcells->empty()) {
|
||||||
for ( size_t i=0 ; i<gcells->size()-1 ; ++i )
|
for ( size_t i=0 ; i<gcells->size()-1 ; ++i ) {
|
||||||
gcells->gcellAt(i)->getEdgeAt( side, axis )->reserveCapacity( elementCapacity );
|
Edge* edge = gcells->gcellAt(i)->getEdgeAt( side, axis );
|
||||||
|
edge->reserveCapacity( elementCapacity );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,6 +531,15 @@ namespace Katana {
|
||||||
edge->reserveCapacity( capacity );
|
edge->reserveCapacity( capacity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for ( GCell* gcell : getGCells() ) {
|
||||||
|
if (not gcell->isMatrix()) continue;
|
||||||
|
|
||||||
|
for ( Edge* edge : gcell->getEdges( Flags::EastSide|Flags::NorthSide) ) {
|
||||||
|
if (edge->getReservedCapacity() == 0)
|
||||||
|
edge->reserveCapacity( 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1152,7 +1152,9 @@ namespace Katana {
|
||||||
float reserve = (_segment->isLocal()) ? 0.5 : 1.0;
|
float reserve = (_segment->isLocal()) ? 0.5 : 1.0;
|
||||||
if (not _segment->canMoveUp(reserve)) return false;
|
if (not _segment->canMoveUp(reserve)) return false;
|
||||||
|
|
||||||
return _segment->moveUp( Flags::NoFlags );
|
//reprocessParallels();
|
||||||
|
bool success = _segment->moveUp( Flags::NoFlags );
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1193,7 +1195,9 @@ namespace Katana {
|
||||||
if (not _segment->canMoveUp(0.5,kflags)) return false;
|
if (not _segment->canMoveUp(0.5,kflags)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//reprocessParallels();
|
||||||
bool success = _segment->moveUp( kflags|Flags::Propagate );
|
bool success = _segment->moveUp( kflags|Flags::Propagate );
|
||||||
|
|
||||||
_fsm.addAction ( _segment, SegmentAction::OtherRipup );
|
_fsm.addAction ( _segment, SegmentAction::OtherRipup );
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -1573,6 +1577,45 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Manipulator::reprocessParallels ()
|
||||||
|
{
|
||||||
|
cdebug_log(159,0) << "Manipulator::reprocessParallels() " << _segment << endl;
|
||||||
|
|
||||||
|
//if (_event->getPerpandiculars().size() > 2) return;
|
||||||
|
|
||||||
|
unsigned int rpDistance = _segment->base()->getRpDistance();
|
||||||
|
|
||||||
|
const vector<TrackElement*>& perpandiculars = _event->getPerpandiculars();
|
||||||
|
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
|
||||||
|
TrackElement* perpandicular = perpandiculars[iperpand];
|
||||||
|
DataNegociate* data = perpandicular->getDataNegociate();
|
||||||
|
|
||||||
|
if (perpandicular->isFixed()) continue;
|
||||||
|
if (not data) continue;
|
||||||
|
if (not perpandicular->getTrack()) continue;
|
||||||
|
if (perpandicular->base()->getRpDistance() > rpDistance) continue;
|
||||||
|
if (not Manipulator(perpandicular,_fsm).canRipup()
|
||||||
|
or (data->getState() >= DataNegociate::MaximumSlack)) continue;
|
||||||
|
|
||||||
|
_fsm.addAction( perpandicular, SegmentAction::SelfRipupPerpand );
|
||||||
|
|
||||||
|
const vector<TrackElement*>& parallels = data->getRoutingEvent()->getPerpandiculars();
|
||||||
|
for ( size_t iparallel=0 ; iparallel<parallels.size() ; iparallel++ ) {
|
||||||
|
TrackElement* parallel = parallels[iparallel];
|
||||||
|
DataNegociate* data = parallel->getDataNegociate();
|
||||||
|
|
||||||
|
if (parallel->isFixed()) continue;
|
||||||
|
if (not data) continue;
|
||||||
|
if (not parallel->getTrack()) continue;
|
||||||
|
if (parallel->base()->getRpDistance() > rpDistance) continue;
|
||||||
|
if (not Manipulator(parallel,_fsm).canRipup()
|
||||||
|
or (data->getState() >= DataNegociate::MaximumSlack)) continue;
|
||||||
|
|
||||||
|
_fsm.addAction( parallel, SegmentAction::SelfRipupPerpand );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Manipulator::reprocessPerpandiculars ()
|
void Manipulator::reprocessPerpandiculars ()
|
||||||
{
|
{
|
||||||
if ( _event->getAxisHistory() == _event->getAxisHint() ) return;
|
if ( _event->getAxisHistory() == _event->getAxisHint() ) return;
|
||||||
|
@ -1640,4 +1683,68 @@ namespace Katana {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Manipulator::avoidBlockage ()
|
||||||
|
{
|
||||||
|
cdebug_log(159,1) << "Manipulator::avoidBlockage()" << endl;
|
||||||
|
|
||||||
|
if (not _segment->isVertical()) {
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoContact* terminal = _segment->base()->getAutoSource();
|
||||||
|
AutoContact* turn = _segment->base()->getAutoTarget();
|
||||||
|
bool isSourceTerminal = true;
|
||||||
|
|
||||||
|
if (not terminal->isTerminal()) {
|
||||||
|
std::swap( terminal, turn );
|
||||||
|
isSourceTerminal = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TrackElement* perpandicular = _event->getPerpandiculars()[0];
|
||||||
|
DataNegociate* data = perpandicular->getDataNegociate();
|
||||||
|
|
||||||
|
if (not data or (data->getState() >= DataNegociate::RepairFailed)) {
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Box termConstraints ( terminal->getConstraintBox() );
|
||||||
|
Box turnConstraints ( turn ->getConstraintBox() );
|
||||||
|
|
||||||
|
if (isSourceTerminal) {
|
||||||
|
terminal->setConstraintBox( Box( termConstraints.getXMin()
|
||||||
|
, termConstraints.getYMin()
|
||||||
|
, termConstraints.getXMax()
|
||||||
|
, perpandicular->getAxis() - perpandicular->getPitch()
|
||||||
|
) );
|
||||||
|
turn->setConstraintBox( Box( turnConstraints.getXMin()
|
||||||
|
, turnConstraints.getYMin()
|
||||||
|
, turnConstraints.getXMax()
|
||||||
|
, perpandicular->getAxis() - perpandicular->getPitch()
|
||||||
|
) );
|
||||||
|
} else {
|
||||||
|
terminal->setConstraintBox( Box( termConstraints.getXMin()
|
||||||
|
, perpandicular->getAxis() + perpandicular->getPitch()
|
||||||
|
, termConstraints.getXMax()
|
||||||
|
, termConstraints.getYMax()
|
||||||
|
) );
|
||||||
|
turn->setConstraintBox( Box( turnConstraints.getXMin()
|
||||||
|
, perpandicular->getAxis() + perpandicular->getPitch()
|
||||||
|
, turnConstraints.getXMax()
|
||||||
|
, turnConstraints.getYMax()
|
||||||
|
) );
|
||||||
|
}
|
||||||
|
|
||||||
|
cdebug_log(159,0) << "Restrict: " << terminal << " to " << terminal->getConstraintBox() << endl;
|
||||||
|
cdebug_log(159,0) << "Restrict: " << turn << " to " << turn ->getConstraintBox() << endl;
|
||||||
|
|
||||||
|
_fsm.addAction ( perpandicular, SegmentAction::SelfRipupPerpand|SegmentAction::EventLevel4 );
|
||||||
|
|
||||||
|
cdebug_tabw(159,-1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // Katana namespace.
|
} // Katana namespace.
|
||||||
|
|
|
@ -377,14 +377,14 @@ namespace Katana {
|
||||||
cdebug_log(159,0) << "* Nearest " << track << endl;
|
cdebug_log(159,0) << "* Nearest " << track << endl;
|
||||||
|
|
||||||
if (not track)
|
if (not track)
|
||||||
throw Error( "NegociateWindow::createTracksegment(): No track near axis of %s."
|
throw Error( "NegociateWindow::createTrackSegment(): No track near axis of %s."
|
||||||
, getString(autoSegment).c_str() );
|
, getString(autoSegment).c_str() );
|
||||||
|
|
||||||
if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack();
|
if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack();
|
||||||
if (track->getAxis() < uside.getVMin()) track = track->getNextTrack();
|
if (track->getAxis() < uside.getVMin()) track = track->getNextTrack();
|
||||||
|
|
||||||
if (not track)
|
if (not track)
|
||||||
throw Error( "NegociateWindow::createTracksegment(): No track near axis of %s (after adjust)."
|
throw Error( "NegociateWindow::createTrackSegment(): No track near axis of %s (after adjust)."
|
||||||
, getString(autoSegment).c_str() );
|
, getString(autoSegment).c_str() );
|
||||||
|
|
||||||
cdebug_log(159,0) << "* GCell U-side " << uside << endl;
|
cdebug_log(159,0) << "* GCell U-side " << uside << endl;
|
||||||
|
|
|
@ -562,11 +562,22 @@ namespace {
|
||||||
axisMax += delta;
|
axisMax += delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (segment->getId() == 51904) {
|
||||||
|
// DebugSession::open( 0, 1000 );
|
||||||
|
// }
|
||||||
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
|
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
|
||||||
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) {
|
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) {
|
||||||
TrackElement* element = TrackFixedSegment::create ( track, segment );
|
TrackElement* element = TrackFixedSegment::create ( track, segment );
|
||||||
cdebug_log(159,0) << " Insert in " << track << "+" << element << endl;
|
cdebug_log(159,0) << " Insert in " << track << "+" << element << endl;
|
||||||
|
|
||||||
|
if (segment->getId() == 51904) {
|
||||||
|
cerr << " Insert in " << track << endl;
|
||||||
|
cerr << " +" << element << endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// if (segment->getId() == 51904) {
|
||||||
|
// DebugSession::close();
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
list<Interval>::iterator ichunk = _chunks.begin();
|
list<Interval>::iterator ichunk = _chunks.begin();
|
||||||
|
|
|
@ -999,7 +999,7 @@ namespace Katana {
|
||||||
<< " " << candidates[icandidate].getTrack() << endl;
|
<< " " << candidates[icandidate].getTrack() << endl;
|
||||||
|
|
||||||
Interval overlap0 = candidates[icandidate].getLongestConflict();
|
Interval overlap0 = candidates[icandidate].getLongestConflict();
|
||||||
cdebug_log(159,0) << "overlap0: " << overlap0 << endl;
|
cdebug_log(159,0) << "| overlap0: " << overlap0 << endl;
|
||||||
|
|
||||||
if (overlap0.isEmpty()) {
|
if (overlap0.isEmpty()) {
|
||||||
cdebug_log(159,0) << "overlap0 is empty, no conflict, ignoring Track candidate." << endl;
|
cdebug_log(159,0) << "overlap0 is empty, no conflict, ignoring Track candidate." << endl;
|
||||||
|
@ -1009,9 +1009,15 @@ namespace Katana {
|
||||||
Track* track = candidates[icandidate].getTrack();
|
Track* track = candidates[icandidate].getTrack();
|
||||||
TrackElement* other = track->getSegment( overlap.getCenter() );
|
TrackElement* other = track->getSegment( overlap.getCenter() );
|
||||||
if (not other) {
|
if (not other) {
|
||||||
cbug << Error("conflictSolveByPlaceds(): No segment under overlap center.") << endl;
|
cdebug_log(159,0) << "conflictSolveByPlaceds(): No segment under overlap center." << endl;
|
||||||
continue;
|
other = track->getSegment( overlap0.getCenter() );
|
||||||
|
|
||||||
|
if (not other) {
|
||||||
|
cdebug_log(159,0) << "conflictSolveByPlaceds(): No segment under overlap0 center." << endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
cdebug_log(159,0) << "| other: " << other << endl;
|
||||||
|
|
||||||
if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) {
|
if (Session::getConfiguration()->isVH() and (segment->getDepth() == 1)) {
|
||||||
if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) {
|
if (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) {
|
||||||
|
@ -1020,6 +1026,7 @@ namespace Katana {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
cdebug_log(159,0) << "conflictSolveByPlaceds() other->isGlobal():" << other->isGlobal() << endl;
|
||||||
if (other->isGlobal()) {
|
if (other->isGlobal()) {
|
||||||
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
|
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
|
||||||
if ((success = Manipulator(other,*this).moveUp(Manipulator::IgnoreContacts))) break;
|
if ((success = Manipulator(other,*this).moveUp(Manipulator::IgnoreContacts))) break;
|
||||||
|
@ -1204,6 +1211,11 @@ namespace Katana {
|
||||||
switch ( data->getState() ) {
|
switch ( data->getState() ) {
|
||||||
case DataNegociate::RipupPerpandiculars:
|
case DataNegociate::RipupPerpandiculars:
|
||||||
nextState = DataNegociate::Minimize;
|
nextState = DataNegociate::Minimize;
|
||||||
|
if (segment->isNonPref() and getCost(0)->isBlockage()) {
|
||||||
|
cdebug_log(159,0) << "Non-preferred conflicts with a blockage." << endl;
|
||||||
|
success = manipulator.avoidBlockage();
|
||||||
|
if (success) break;
|
||||||
|
}
|
||||||
success = manipulator.ripupPerpandiculars();
|
success = manipulator.ripupPerpandiculars();
|
||||||
if (success) break;
|
if (success) break;
|
||||||
case DataNegociate::Minimize:
|
case DataNegociate::Minimize:
|
||||||
|
|
|
@ -161,6 +161,8 @@ namespace Katana {
|
||||||
size_t begin;
|
size_t begin;
|
||||||
|
|
||||||
getBeginIndex( position, begin, state );
|
getBeginIndex( position, begin, state );
|
||||||
|
cdebug_log(159,0) << " getSegment(position): begin:" << begin << endl;
|
||||||
|
|
||||||
if (state & (BeginIsTrackMin|EndIsTrackMax)) return NULL;
|
if (state & (BeginIsTrackMin|EndIsTrackMax)) return NULL;
|
||||||
return getSegment(begin);
|
return getSegment(begin);
|
||||||
}
|
}
|
||||||
|
@ -237,21 +239,26 @@ namespace Katana {
|
||||||
// I guess this has been written for the case of overlapping segments from the same
|
// I guess this has been written for the case of overlapping segments from the same
|
||||||
// net, we find the first one of the overlapped sets. But what if they are not overlapping
|
// net, we find the first one of the overlapped sets. But what if they are not overlapping
|
||||||
// but still from the same net?
|
// but still from the same net?
|
||||||
|
cdebug_log(159,0) << " begin:" << begin << endl;
|
||||||
size_t sameNetDelta = 0;
|
size_t sameNetDelta = 0;
|
||||||
if (begin < _segments.size()) {
|
if (begin < _segments.size()) {
|
||||||
for ( ; (begin > 0) and (_segments[begin-1]->getNet() == _segments[begin]->getNet())
|
for ( ; (begin > 0) and (_segments[begin-1]->getNet() == _segments[begin]->getNet())
|
||||||
; --begin, ++sameNetDelta );
|
; --begin, ++sameNetDelta );
|
||||||
}
|
}
|
||||||
|
cdebug_log(159,0) << " begin:" << begin << endl;
|
||||||
|
|
||||||
state = 0;
|
state = 0;
|
||||||
if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) {
|
if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) {
|
||||||
state = BeforeFirstElement;
|
state = BeforeFirstElement;
|
||||||
} else {
|
} else {
|
||||||
if (begin and not sameNetDelta) begin -= 1;
|
if (begin and not sameNetDelta) begin -= 1;
|
||||||
|
cdebug_log(159,0) << " begin:" << begin << endl;
|
||||||
|
|
||||||
size_t usedBegin = begin;
|
size_t usedBegin = begin;
|
||||||
Interval usedInterval = getOccupiedInterval( usedBegin );
|
Interval usedInterval = getOccupiedInterval( usedBegin );
|
||||||
|
|
||||||
|
cdebug_log(159,0) << " position:" << DbU::getValueString(position)
|
||||||
|
<< " " << usedInterval << endl;
|
||||||
if (position < usedInterval.getVMax())
|
if (position < usedInterval.getVMax())
|
||||||
state = InsideElement;
|
state = InsideElement;
|
||||||
else
|
else
|
||||||
|
|
|
@ -253,7 +253,7 @@ namespace Katana {
|
||||||
string s2 = " [" + DbU::getValueString(_sourceU)
|
string s2 = " [" + DbU::getValueString(_sourceU)
|
||||||
+ ":" + DbU::getValueString(_targetU) + "]"
|
+ ":" + DbU::getValueString(_targetU) + "]"
|
||||||
+ " " + DbU::getValueString(_targetU-_sourceU)
|
+ " " + DbU::getValueString(_targetU-_sourceU)
|
||||||
+ "F"
|
+ " F"
|
||||||
+ ((isBlockage()) ? "B" : "-");
|
+ ((isBlockage()) ? "B" : "-");
|
||||||
s1.insert ( s1.size()-1, s2 );
|
s1.insert ( s1.size()-1, s2 );
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ namespace Katana {
|
||||||
trackElement->_postCreate();
|
trackElement->_postCreate();
|
||||||
trackElement->invalidate();
|
trackElement->invalidate();
|
||||||
created = true;
|
created = true;
|
||||||
cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" <<useNonPref
|
cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" << useNonPref
|
||||||
<< " " << trackElement << endl;
|
<< " " << trackElement << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ namespace Katana {
|
||||||
uint32_t getRipupLimit ( uint32_t type ) const;
|
uint32_t getRipupLimit ( uint32_t type ) const;
|
||||||
inline uint32_t getHTracksReservedLocal () const;
|
inline uint32_t getHTracksReservedLocal () const;
|
||||||
inline uint32_t getVTracksReservedLocal () const;
|
inline uint32_t getVTracksReservedLocal () const;
|
||||||
|
inline uint32_t getTermSatReservedLocal () const;
|
||||||
|
inline uint32_t getTermSatThreshold () const;
|
||||||
inline void setEventsLimit ( uint64_t );
|
inline void setEventsLimit ( uint64_t );
|
||||||
inline void setRipupCost ( uint32_t );
|
inline void setRipupCost ( uint32_t );
|
||||||
void setRipupLimit ( uint32_t limit, uint32_t type );
|
void setRipupLimit ( uint32_t limit, uint32_t type );
|
||||||
|
@ -89,6 +91,8 @@ namespace Katana {
|
||||||
PostEventCb_t _postEventCb;
|
PostEventCb_t _postEventCb;
|
||||||
uint32_t _hTracksReservedLocal;
|
uint32_t _hTracksReservedLocal;
|
||||||
uint32_t _vTracksReservedLocal;
|
uint32_t _vTracksReservedLocal;
|
||||||
|
uint32_t _termSatReservedLocal;
|
||||||
|
uint32_t _termSatThreshold;
|
||||||
uint32_t _ripupLimits [RipupLimitsTableSize];
|
uint32_t _ripupLimits [RipupLimitsTableSize];
|
||||||
uint32_t _ripupCost;
|
uint32_t _ripupCost;
|
||||||
uint64_t _eventsLimit;
|
uint64_t _eventsLimit;
|
||||||
|
@ -108,6 +112,8 @@ namespace Katana {
|
||||||
inline uint32_t Configuration::getRipupCost () const { return _ripupCost; }
|
inline uint32_t Configuration::getRipupCost () const { return _ripupCost; }
|
||||||
inline uint32_t Configuration::getHTracksReservedLocal () const { return _hTracksReservedLocal; }
|
inline uint32_t Configuration::getHTracksReservedLocal () const { return _hTracksReservedLocal; }
|
||||||
inline uint32_t Configuration::getVTracksReservedLocal () const { return _vTracksReservedLocal; }
|
inline uint32_t Configuration::getVTracksReservedLocal () const { return _vTracksReservedLocal; }
|
||||||
|
inline uint32_t Configuration::getTermSatReservedLocal () const { return _termSatReservedLocal; }
|
||||||
|
inline uint32_t Configuration::getTermSatThreshold () const { return _termSatThreshold; }
|
||||||
inline void Configuration::setRipupCost ( uint32_t cost ) { _ripupCost = cost; }
|
inline void Configuration::setRipupCost ( uint32_t cost ) { _ripupCost = cost; }
|
||||||
inline void Configuration::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; }
|
inline void Configuration::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; }
|
||||||
inline void Configuration::setEventsLimit ( uint64_t limit ) { _eventsLimit = limit; }
|
inline void Configuration::setEventsLimit ( uint64_t limit ) { _eventsLimit = limit; }
|
||||||
|
|
|
@ -84,6 +84,8 @@ namespace Katana {
|
||||||
inline uint32_t getRipupCost () const;
|
inline uint32_t getRipupCost () const;
|
||||||
inline uint32_t getHTracksReservedLocal () const;
|
inline uint32_t getHTracksReservedLocal () const;
|
||||||
inline uint32_t getVTracksReservedLocal () const;
|
inline uint32_t getVTracksReservedLocal () const;
|
||||||
|
inline uint32_t getTermSatReservedLocal () const;
|
||||||
|
inline uint32_t getTermSatThreshold () const;
|
||||||
inline bool profileEventCosts () const;
|
inline bool profileEventCosts () const;
|
||||||
virtual const Name& getName () const;
|
virtual const Name& getName () const;
|
||||||
inline Configuration::PostEventCb_t&
|
inline Configuration::PostEventCb_t&
|
||||||
|
@ -183,6 +185,8 @@ namespace Katana {
|
||||||
inline uint32_t KatanaEngine::getRipupCost () const { return _configuration->getRipupCost(); }
|
inline uint32_t KatanaEngine::getRipupCost () const { return _configuration->getRipupCost(); }
|
||||||
inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); }
|
inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); }
|
||||||
inline uint32_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); }
|
inline uint32_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); }
|
||||||
|
inline uint32_t KatanaEngine::getTermSatReservedLocal () const { return _configuration->getTermSatReservedLocal(); }
|
||||||
|
inline uint32_t KatanaEngine::getTermSatThreshold () const { return _configuration->getTermSatThreshold(); }
|
||||||
inline uint32_t KatanaEngine::getRipupLimit ( uint32_t type ) const { return _configuration->getRipupLimit(type); }
|
inline uint32_t KatanaEngine::getRipupLimit ( uint32_t type ) const { return _configuration->getRipupLimit(type); }
|
||||||
inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); }
|
inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); }
|
||||||
inline const DataSymmetricMap& KatanaEngine::getSymmetrics () const { return _symmetrics; }
|
inline const DataSymmetricMap& KatanaEngine::getSymmetrics () const { return _symmetrics; }
|
||||||
|
|
|
@ -65,6 +65,8 @@ namespace Katana {
|
||||||
bool ripupPerpandiculars ( uint32_t flags=0 );
|
bool ripupPerpandiculars ( uint32_t flags=0 );
|
||||||
void repackPerpandiculars ( uint32_t flags );
|
void repackPerpandiculars ( uint32_t flags );
|
||||||
void reprocessPerpandiculars ();
|
void reprocessPerpandiculars ();
|
||||||
|
void reprocessParallels ();
|
||||||
|
bool avoidBlockage ();
|
||||||
bool ripple ();
|
bool ripple ();
|
||||||
bool minimize ();
|
bool minimize ();
|
||||||
bool dragMinimize ();
|
bool dragMinimize ();
|
||||||
|
|
Loading…
Reference in New Issue