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:
Jean-Paul Chaput 2019-09-17 17:05:54 +02:00
parent c6ea1bccdd
commit 24dedce09c
43 changed files with 1064 additions and 143 deletions

View File

@ -170,28 +170,67 @@ namespace Anabatic {
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();
Point sourcePosition = segment->getSourcePosition();
Point targetPosition = segment->getTargetPosition();
commonCtor( engine, segment->getSourcePosition(), segment->getTargetPosition() );
if ( (sourcePosition.getX() > gcellsArea.getXMax())
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)."
, getString(segment).c_str()
cdebug_tabw(112,-1);
}
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Point source, Point target )
{
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;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
DbU::Unit xsource = std::max( sourcePosition.getX(), gcellsArea.getXMin() );
DbU::Unit ysource = std::max( sourcePosition.getY(), gcellsArea.getYMin() );
DbU::Unit xtarget = std::min( targetPosition.getX(), gcellsArea.getXMax() );
DbU::Unit ytarget = std::min( targetPosition.getY(), gcellsArea.getYMax() );
if ( (source.getX() > gcellsArea.getXMax())
or (source.getY() > gcellsArea.getYMax())
or (target.getX() <= gcellsArea.getXMin())
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 (ytarget == gcellsArea.getYMax()) --ytarget;
@ -200,16 +239,14 @@ namespace Anabatic {
GCell* gtarget = engine->getGCellUnder( xtarget, ytarget );
if (not gsource) {
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s source not under a GCell (ignored)."
, getString(segment).c_str()
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)."
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
if (not gtarget) {
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s target not under a GCell (ignored)."
, getString(segment).c_str()
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)."
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
@ -223,24 +260,6 @@ namespace Anabatic {
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;
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
{
cdebug_log(149,1) << "Checking " << net << endl;

View File

@ -194,7 +194,7 @@ namespace Anabatic {
// SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on
// their extremities. Should modificate all the standard cells layout...
// HARDCODED.
if (Session::getRoutingGauge()->getName() == "msxlib")
if (getString(Session::getRoutingGauge()->getName()).substr(0,6) == "msxlib")
yborder -= DbU::fromLambda( 1.0 );
else
yborder -= DbU::fromLambda( 0.5 );

View File

@ -1076,7 +1076,7 @@ namespace Anabatic {
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;

View File

@ -77,8 +77,8 @@ namespace Anabatic {
, _cg (NULL)
, _rg (NULL)
, _extensionCaps ()
, _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
, _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt())
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble())
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt())
, _globalThreshold (0)
, _allowedDepth (0)
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))

View File

@ -118,6 +118,7 @@ namespace Anabatic {
const BaseFlags Flags::NoUpdate = (1L << 32);
const BaseFlags Flags::NorthPath = (1L << 33);
const BaseFlags Flags::UseNonPref = (1L << 34);
const BaseFlags Flags::Force = (1L << 35);
Flags::~Flags ()

View File

@ -298,6 +298,7 @@ namespace Anabatic {
, _contacts ()
, _depth (Session::getRoutingGauge()->getDepth())
, _pinDepth (0)
, _rpCount (0)
, _blockages (new DbU::Unit [_depth])
, _cDensity (0.0)
, _densities (new float [_depth])
@ -1790,6 +1791,7 @@ namespace Anabatic {
string s = Super::_getString();
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
s.insert( s.size()-1, " "+getString(_flags) );
s.insert( s.size()-1, " "+getString(_rpCount) );
/* string s = "<GCell at(" + DbU::getValueString(getXMin())
+ "-" + DbU::getValueString(getYMin())
+ "-" + DbU::getValueString(getXMax())

View File

@ -349,7 +349,7 @@ namespace Anabatic {
size_t i = 0;
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
if (not (*igcell)->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;

View File

@ -616,6 +616,8 @@ namespace Anabatic {
case Conn_4G: _do_xG(); break;
// End xG cascaded 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_2G_1PinM2:
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
@ -628,7 +630,7 @@ namespace Anabatic {
default:
if (not isTwoMetals())
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.fields.globals
, _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 ()
{
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );

View File

@ -32,6 +32,7 @@
#include "hurricane/RoutingPad.h"
#include "hurricane/RoutingPads.h"
#include "hurricane/Pad.h"
#include "hurricane/Pin.h"
#include "hurricane/Plug.h"
#include "hurricane/Cell.h"
#include "hurricane/Instance.h"
@ -54,6 +55,8 @@ namespace Anabatic {
using std::swap;
using Hurricane::Transformation;
using Hurricane::Warning;
using Hurricane::Error;
using Hurricane::Pin;
NetBuilderHV::NetBuilderHV ()
@ -105,7 +108,7 @@ namespace Anabatic {
}
// 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 );
if (irp == getRpLookup().end()) {
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 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpSourceContact = NULL;
AutoContact* rpContactTarget = NULL;
AutoContact* turn = NULL;
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 (west() and south()) {
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );

View File

@ -68,6 +68,8 @@ namespace Anabatic {
};
public:
RawGCellsUnder ( const AnabaticEngine*, Segment* );
RawGCellsUnder ( const AnabaticEngine*, Point source, Point target );
void commonCtor ( const AnabaticEngine*, Point source, Point target );
inline bool empty () const;
inline size_t size () 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 ( Point ) 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;
Interval getUSide ( Flags direction ) const;
int getCapacity ( Interval, Flags ) const;
@ -255,6 +258,7 @@ namespace Anabatic {
inline void setSaturateRp ( size_t );
inline void setBlockageNet ( Net* );
void chipPrep ();
void computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat );
void setupSpecialNets ();
size_t setupPreRouteds ();
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 ( 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 ( 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 uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }

View File

@ -101,6 +101,7 @@ namespace Anabatic {
static const BaseFlags NoUpdate ;
static const BaseFlags NorthPath ;
static const BaseFlags UseNonPref ;
static const BaseFlags Force ;
public:
inline Flags ( uint64_t flags = NoFlags );
inline Flags ( const Hurricane::BaseFlags& );

View File

@ -217,6 +217,7 @@ namespace Anabatic {
bool hasFreeTrack ( size_t depth, float reserve ) const;
inline size_t getDepth () const;
size_t getNetCount () const;
inline int getRpCount () const;
int getHCapacity () const;
int getVCapacity () const;
int getCapacity ( size_t depth ) const;
@ -264,7 +265,7 @@ namespace Anabatic {
bool stepNetDesaturate ( size_t depth
, set<Net*>& globalNets
, Set& invalidateds );
inline void incRpCount ( int );
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
// Misc. functions.
inline const Flags& flags () const;
@ -321,6 +322,7 @@ namespace Anabatic {
vector<AutoContact*> _contacts;
size_t _depth;
size_t _pinDepth;
int _rpCount;
DbU::Unit* _blockages;
float _cDensity;
float* _densities;
@ -374,7 +376,8 @@ namespace Anabatic {
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
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; }
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
@ -418,6 +421,10 @@ namespace Anabatic {
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 )
{ _observable.setObserver( slot, observer ); }

View File

@ -99,6 +99,7 @@ namespace Anabatic {
, EastBound = (1 << 15)
, Middle = (1 << 16)
, UseNonPref = (1 << 17)
, NoProtect = (1 << 18)
, HBothAccess = HAccess|HAccessEW
, SouthWest = SouthBound|WestBound
, NorthEast = NorthBound|EastBound
@ -204,6 +205,8 @@ namespace Anabatic {
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();
@ -298,6 +301,8 @@ namespace Anabatic {
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 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_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_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )

View File

@ -25,6 +25,7 @@ namespace Anabatic {
// -----------------------------------------------------------------
// Class : "NetBuilderHV".
class NetBuilderHV : public NetBuilder {
public:
NetBuilderHV ();
@ -38,6 +39,8 @@ namespace Anabatic {
virtual bool _do_2G ();
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();

View File

@ -8,7 +8,8 @@ parametersTable = \
, ('etesian.routingDriven' , TypeBool , False )
, ('etesian.feedNames' , TypeString , 'tie_x0,rowend_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
, { 'values':( ("Fast" , 1)

View File

@ -41,6 +41,8 @@ parametersTable = \
)
, ("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 } )

View File

@ -31,10 +31,21 @@ parametersTable = \
, ("anabatic.edgeHInc" ,TypeDouble ,1.0 )
, ("anabatic.edgeHScaling" ,TypeDouble ,1.0 )
, ("anabatic.globalIterations" ,TypeInt ,20 , { 'min':1, 'max':100 } )
, ("anabatic.saturateRatio" ,TypePercentage,80 )
, ("anabatic.gcell.displayMode" ,TypeEnumerate ,1
, { 'values':( ("Boundary" , 1)
, ("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 )
cellGaugesTable = {}
cellGaugesTable['msxlib' ] = ('metal2', l(10), l(100), l(10))
cellGaugesTable['msxlib4'] = ('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['phlib80'] = ('metal2', l(10), l(312), l(246))

View File

@ -30,7 +30,7 @@ allianceConfig = \
, ( 'GROUND' , 'vss')
, ( 'CLOCK' , '^ck.*')
, ( 'BLOCKAGE' , '^blockage[Nn]et*')
, ( 'PAD' , '.*_mpx$')
, ( 'PAD' , '.*_sp$')
# The following are only read by the Alliance tool wrappers.
, ( 'ALLIANCE_TOP' , allianceTop)
, ( 'MBK_TARGET_LIB' , cellsTop+'/msxlib')

View File

@ -3,8 +3,3 @@
import helpers
execfile( helpers.sysConfDir+'/common/etesian.conf' )
parametersTable = \
( ('etesian.bloat' , TypeString , "nsxlib" )
,
)

View File

@ -8,36 +8,45 @@ execfile( helpers.sysConfDir+'/common/kite.conf' )
parametersTable = \
( ('lefImport.minTerminalWidth' ,TypeDouble ,0.0 )
, ("katabatic.globalLengthThreshold",TypeInt ,1450 ) # Katabatic parameters.
, ("katabatic.saturateRatio" ,TypePercentage,80 )
, ("katabatic.saturateRp" ,TypeInt ,8 )
, ('katabatic.topRoutingLayer' ,TypeString , 'METAL3')
# Kite parameters.
, ("kite.hTracksReservedLocal" ,TypeInt ,4 , { 'min':0, 'max':18 } )
, ("kite.vTracksReservedLocal" ,TypeInt ,3 , { 'min':0, 'max':18 } )
, ("kite.eventsLimit" ,TypeInt ,4000002 )
, ("kite.ripupCost" ,TypeInt ,3 , { 'min':0 } )
, ("kite.strapRipupLimit" ,TypeInt ,16 , { 'min':1 } )
, ("kite.localRipupLimit" ,TypeInt ,9 , { 'min':1 } )
, ("kite.globalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
, ("kite.longGlobalRipupLimit" ,TypeInt ,5 , { 'min':1 } )
( ('lefImport.minTerminalWidth' , TypeDouble , 0.0 )
, ("katabatic.globalLengthThreshold", TypeInt , 1450 ) # Katabatic parameters.
, ("katabatic.saturateRatio" , TypePercentage, 80 )
, ("katabatic.saturateRp" , TypeInt , 8 )
, ('katabatic.topRoutingLayer' , TypeString , 'METAL3' )
# Kite parameters.
, ("kite.hTracksReservedLocal" , TypeInt , 4 , { 'min':0, 'max':18 } )
, ("kite.vTracksReservedLocal" , TypeInt , 3 , { 'min':0, 'max':18 } )
, ("kite.eventsLimit" , TypeInt , 4000002 )
, ("kite.ripupCost" , TypeInt , 3 , { 'min':0 } )
, ("kite.strapRipupLimit" , TypeInt , 16 , { 'min':1 } )
, ("kite.localRipupLimit" , TypeInt , 9 , { 'min':1 } )
, ("kite.globalRipupLimit" , TypeInt , 5 , { 'min':1 } )
, ("kite.longGlobalRipupLimit" , TypeInt , 5 , { 'min':1 } )
# Anabatic parameters are temporarily hosted here.
, ('anabatic.topRoutingLayer' ,TypeString , 'METAL3')
, ("anabatic.routingGauge" ,TypeString ,'msxlib3')
, ("anabatic.edgeLength" ,TypeInt ,48 )
, ("anabatic.edgeWidth" ,TypeInt ,8 )
, ("anabatic.edgeCostH" ,TypeDouble ,19.0 )
, ("anabatic.edgeCostK" ,TypeDouble ,-60.0 )
, ("anabatic.edgeHInc" ,TypeDouble ,1.0 )
, ("anabatic.edgeHScaling" ,TypeDouble ,1.0 )
, ("anabatic.globalIterations" ,TypeInt ,20 , { 'min':1, 'max':100 } )
, ("anabatic.gcell.displayMode" ,TypeEnumerate ,1
, ('anabatic.topRoutingLayer' , TypeString , 'METAL3' )
, ("anabatic.routingGauge" , TypeString , 'msxlib3')
, ("anabatic.edgeLength" , TypeInt , 48 )
, ("anabatic.edgeWidth" , TypeInt , 8 )
, ("anabatic.edgeCostH" , TypeDouble , 19.0 )
, ("anabatic.edgeCostK" , TypeDouble , -60.0 )
, ("anabatic.edgeHInc" , TypeDouble , 1.0 )
, ("anabatic.edgeHScaling" , TypeDouble , 1.0 )
, ("anabatic.globalIterations" , TypeInt , 20 , { 'min':1, 'max':100 } )
, ("anabatic.gcell.displayMode" , TypeEnumerate , 1
, { 'values':( ("Boundary" , 1)
, ("Density" , 2) ) }
)
, ("katana.hTracksReservedLocal" , TypeInt , 5 )
, ("katana.vTracksReservedLocal" , TypeInt , 3 )
, ("katana.hTracksReservedLocal" , TypeInt , 5 )
, ("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['msxlib4'] = ('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))

View File

@ -12,7 +12,7 @@ from helpers import l, u, n
#
# Parameters for chip plugin.
parametersTable = \
( ("chip.block.rails.count" , TypeInt , l(5 ) )
( ("chip.block.rails.count" , TypeInt , 5 )
, ("chip.block.rails.hWidth" , TypeInt , l(24) )
, ("chip.block.rails.vWidth" , TypeInt , l(24) )
, ("chip.block.rails.hSpacing" , TypeInt , l(12) )

View File

@ -522,16 +522,17 @@ namespace {
if (layerInfo and net) {
net->setExternal( true );
/*pin =*/ Pin::create( net
, pinName
, accessDirection
, Pin::PlacementStatus::PLACED
, layerInfo->getLayer()
, XCON
, YCON
, WIDTH
, HEIGHT
);
Pin* pin = Pin::create( net
, pinName
, accessDirection
, Pin::PlacementStatus::PLACED
, layerInfo->getLayer()
, XCON
, YCON
, WIDTH
, HEIGHT
);
NetExternalComponents::setExternal( pin );
}
if (not net ) _printError( false, "Unknown net name <%s>." , fields[5] );
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() );
Instance* instance = _cell->getInstance ( instanceName );
if ( instance ) {
if (instance) {
instance->setTransformation
( getTransformation ( instance->getMasterCell()->getAbutmentBox()
, XINS
, YINS
, orient
)
( getTransformation( instance->getMasterCell()->getAbutmentBox()
, XINS
, YINS
, orient
)
);
instance->setPlacementStatus ( Instance::PlacementStatus::FIXED );
instance->setPlacementStatus( Instance::PlacementStatus::FIXED );
} else {
bool ignoreInstance = (getString(masterCellName).substr(0,7) == padreal);
Catalog::State* instanceState = _framework->getCatalog()->getState ( masterCellName );
bool ignoreInstance = _framework->isPad( _cell );
Catalog::State* instanceState = _framework->getCatalog()->getState( masterCellName );
if ( not ignoreInstance and ( not instanceState or (not instanceState->isFeed()) ) ) {
_printError ( false
, "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
// could be in that case.
tab++;
Cell* masterCell = _framework->getCell ( getString(masterCellName)
, Catalog::State::Views
);
Cell* masterCell = _framework->getCell( getString(masterCellName)
, Catalog::State::Views
);
tab--;
if ( !masterCell ) {
_printError ( "Unable to load model %s.", getString(masterCellName).c_str() );
if (not masterCell) {
_printError( "Unable to load model %s.", getString(masterCellName).c_str() );
return;
}
ignoreInstance = ignoreInstance and _cell->isTerminal();
instance = Instance::create ( _cell
, instanceName
, masterCell
, getTransformation ( masterCell->getAbutmentBox()
, XINS
, YINS
, orient
)
, Instance::PlacementStatus::FIXED
, true // Checking of recursive calls
);
_cell->setTerminal ( ignoreInstance );
instance = Instance::create( _cell
, instanceName
, masterCell
, getTransformation ( masterCell->getAbutmentBox()
, XINS
, YINS
, orient
)
, Instance::PlacementStatus::FIXED
, true // Checking of recursive calls
);
_cell->setTerminal( ignoreInstance );
}
}
}

View File

@ -8,6 +8,7 @@
${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py
${CMAKE_CURRENT_SOURCE_DIR}/plugins/CoreToChip_cmos.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/ChipRoute.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/cmos.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
${CMAKE_CURRENT_SOURCE_DIR}/plugins/chip/Configuration.py

View File

@ -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

View File

@ -258,9 +258,6 @@ class Side ( object ):
def check ( self ):
self.validated = True
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()
+ 2*self.conf.minCorona
+ 2*self.conf.getIoPadHeight()
@ -1086,8 +1083,10 @@ class Corona ( object ):
rg = self.conf.gaugeConf.routingGauge
hsegments = { }
vsegments = { }
for component in padNet.getExternalComponents():
if isinstance(component,Segment):
if isinstance(component,Segment) or isinstance(component,Contact):
bb = component.getBoundingBox()
padInstance.getTransformation().applyOn( bb )
if bb.intersect(innerBb):
@ -1136,6 +1135,16 @@ class Corona ( object ):
side.updateGap ( gapWidth )
side.addCoreWire( CoreWire( self, chipIntNet, segment, bb, side.type, inPreferredDir, count ) )
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

View File

@ -138,7 +138,9 @@ class IoNet ( object ):
# Chip "external" net, connected to the pad I/O to the outside world.
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.setDirection( self.coreNet.getDirection() )
@ -190,6 +192,7 @@ class IoPad ( object ):
if len(self.nets) == 1:
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.getName() == 'scout': self.direction = IoPad.OUT
else:
raise ErrorMessage( 1, 'IoPad.addNet(): Unsupported direction %d (%s) for core net "%s" in I/O pad \"%s\".' \
% ( self.nets[0].coreNet.getDirection()
@ -339,7 +342,9 @@ class CoreToChip ( object ):
for ringNetSpec in self.ringNetNames:
if isinstance(ringNetSpec,tuple): ringNetName = ringNetSpec[0]
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.setGlobal( self.isGlobal (ringNetName) )
return

View File

@ -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

View File

@ -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

View File

@ -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 )
{
BloatKey key ( profile );

View File

@ -82,6 +82,14 @@ namespace Etesian {
virtual ~BloatNsxlib ();
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 {
@ -108,6 +116,7 @@ namespace Etesian {
{
_bloatCells.insert( new BloatDisabled() );
_bloatCells.insert( new BloatNsxlib () );
_bloatCells.insert( new Bloat3Metals () );
select( "disabled" );
}

View File

@ -42,6 +42,8 @@ namespace Katana {
, _postEventCb ()
, _hTracksReservedLocal(Cfg::getParamInt ("katana.hTracksReservedLocal", 3)->asInt())
, _vTracksReservedLocal(Cfg::getParamInt ("katana.vTracksReservedLocal", 3)->asInt())
, _termSatReservedLocal(Cfg::getParamInt ("katana.termSatReservedLocal", 9)->asInt())
, _termSatThreshold (Cfg::getParamInt ("katana.termSatThreshold" , 8)->asInt())
, _ripupLimits ()
, _ripupCost (Cfg::getParamInt ("katana.ripupCost" , 3)->asInt())
, _eventsLimit (Cfg::getParamInt ("katana.eventsLimit" ,4000000)->asInt())
@ -80,6 +82,8 @@ namespace Katana {
, _postEventCb (other._postEventCb)
, _hTracksReservedLocal(other._hTracksReservedLocal)
, _vTracksReservedLocal(other._vTracksReservedLocal)
, _termSatReservedLocal(other._termSatReservedLocal)
, _termSatThreshold (other._termSatThreshold)
, _ripupLimits ()
, _ripupCost (other._ripupCost)
, _eventsLimit (other._eventsLimit)
@ -148,13 +152,16 @@ namespace Katana {
if (not cmess1.enabled()) return;
cout << " o Configuration of ToolEngine<Katana> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asUInt (" - Global router H reserved local" ,_hTracksReservedLocal) << endl;
cout << Dots::asUInt (" - Global router V reserved local" ,_vTracksReservedLocal) << endl;
cout << Dots::asULong(" - Events limit (iterations)" ,_eventsLimit) << 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;
cout << Dots::asDouble(" - GCell saturate ratio (LA)" ,getSaturateRatio()) << endl;
cout << Dots::asUInt (" - Edge max H reserved local" ,_hTracksReservedLocal) << endl;
cout << Dots::asUInt (" - Edge max V reserved local" ,_vTracksReservedLocal) << endl;
cout << Dots::asUInt (" - Terminal saturated edge capacity" ,_termSatReservedLocal) << endl;
cout << Dots::asUInt (" - Terminal saturated GCell threshold" ,_termSatThreshold) << endl;
cout << Dots::asULong (" - Events limit (iterations)" ,_eventsLimit) << 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 );
}

View File

@ -228,7 +228,13 @@ namespace Katana {
printMeasures( "Anabatic Grid" );
setupNetDatas();
computeEdgeCapacities( getHTracksReservedLocal()
, getVTracksReservedLocal()
, getTermSatThreshold()
, getTermSatReservedLocal()
);
#if UNIFORM_EDGE_CAPACITY
for ( GCell* gcell : getGCells() ) {
if (not gcell->isMatrix()) continue;
@ -237,6 +243,7 @@ namespace Katana {
else edge->reserveCapacity( getVTracksReservedLocal() );
}
}
#endif
}

View File

@ -480,19 +480,28 @@ namespace Katana {
Segment* segment = element->getSegment();
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) {
side = Flags::NorthSide;
axis = segment->getX();
source.setX( axis );
target.setX( axis );
} else {
source.setY( axis );
target.setY( axis );
}
int elementCapacity = 1;
cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl;
GCellsUnder gcells = getGCellsUnder( segment );
GCellsUnder gcells = getGCellsUnder( source, target );
if (not gcells->empty()) {
for ( size_t i=0 ; i<gcells->size()-1 ; ++i )
gcells->gcellAt(i)->getEdgeAt( side, axis )->reserveCapacity( elementCapacity );
for ( size_t i=0 ; i<gcells->size()-1 ; ++i ) {
Edge* edge = gcells->gcellAt(i)->getEdgeAt( side, axis );
edge->reserveCapacity( elementCapacity );
}
}
}
}
@ -522,6 +531,15 @@ namespace Katana {
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 );
}
}
}
}

View File

@ -1152,7 +1152,9 @@ namespace Katana {
float reserve = (_segment->isLocal()) ? 0.5 : 1.0;
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;
}
//reprocessParallels();
bool success = _segment->moveUp( kflags|Flags::Propagate );
_fsm.addAction ( _segment, SegmentAction::OtherRipup );
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 ()
{
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.

View File

@ -377,14 +377,14 @@ namespace Katana {
cdebug_log(159,0) << "* Nearest " << track << endl;
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() );
if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack();
if (track->getAxis() < uside.getVMin()) track = track->getNextTrack();
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() );
cdebug_log(159,0) << "* GCell U-side " << uside << endl;

View File

@ -562,11 +562,22 @@ namespace {
axisMax += delta;
}
// if (segment->getId() == 51904) {
// DebugSession::open( 0, 1000 );
// }
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) {
TrackElement* element = TrackFixedSegment::create ( track, segment );
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 {
list<Interval>::iterator ichunk = _chunks.begin();

View File

@ -999,7 +999,7 @@ namespace Katana {
<< " " << candidates[icandidate].getTrack() << endl;
Interval overlap0 = candidates[icandidate].getLongestConflict();
cdebug_log(159,0) << "overlap0: " << overlap0 << endl;
cdebug_log(159,0) << "| overlap0: " << overlap0 << endl;
if (overlap0.isEmpty()) {
cdebug_log(159,0) << "overlap0 is empty, no conflict, ignoring Track candidate." << endl;
@ -1009,9 +1009,15 @@ namespace Katana {
Track* track = candidates[icandidate].getTrack();
TrackElement* other = track->getSegment( overlap.getCenter() );
if (not other) {
cbug << Error("conflictSolveByPlaceds(): No segment under overlap center.") << endl;
continue;
cdebug_log(159,0) << "conflictSolveByPlaceds(): No segment under overlap center." << endl;
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 (Manipulator(segment,*this).makeDogleg(overlap0,Flags::ShortDogleg)) {
@ -1020,6 +1026,7 @@ namespace Katana {
break;
}
} else {
cdebug_log(159,0) << "conflictSolveByPlaceds() other->isGlobal():" << other->isGlobal() << endl;
if (other->isGlobal()) {
cdebug_log(159,0) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl;
if ((success = Manipulator(other,*this).moveUp(Manipulator::IgnoreContacts))) break;
@ -1204,6 +1211,11 @@ namespace Katana {
switch ( data->getState() ) {
case DataNegociate::RipupPerpandiculars:
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();
if (success) break;
case DataNegociate::Minimize:

View File

@ -161,6 +161,8 @@ namespace Katana {
size_t begin;
getBeginIndex( position, begin, state );
cdebug_log(159,0) << " getSegment(position): begin:" << begin << endl;
if (state & (BeginIsTrackMin|EndIsTrackMax)) return NULL;
return getSegment(begin);
}
@ -237,21 +239,26 @@ namespace Katana {
// 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
// but still from the same net?
cdebug_log(159,0) << " begin:" << begin << endl;
size_t sameNetDelta = 0;
if (begin < _segments.size()) {
for ( ; (begin > 0) and (_segments[begin-1]->getNet() == _segments[begin]->getNet())
; --begin, ++sameNetDelta );
}
cdebug_log(159,0) << " begin:" << begin << endl;
state = 0;
if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) {
state = BeforeFirstElement;
} else {
if (begin and not sameNetDelta) begin -= 1;
cdebug_log(159,0) << " begin:" << begin << endl;
size_t usedBegin = begin;
Interval usedInterval = getOccupiedInterval( usedBegin );
cdebug_log(159,0) << " position:" << DbU::getValueString(position)
<< " " << usedInterval << endl;
if (position < usedInterval.getVMax())
state = InsideElement;
else

View File

@ -253,7 +253,7 @@ namespace Katana {
string s2 = " [" + DbU::getValueString(_sourceU)
+ ":" + DbU::getValueString(_targetU) + "]"
+ " " + DbU::getValueString(_targetU-_sourceU)
+ "F"
+ " F"
+ ((isBlockage()) ? "B" : "-");
s1.insert ( s1.size()-1, s2 );

View File

@ -156,7 +156,7 @@ namespace Katana {
trackElement->_postCreate();
trackElement->invalidate();
created = true;
cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" <<useNonPref
cdebug_log(159,0) << "TrackSegment::create(): " << "nonPref:" << useNonPref
<< " " << trackElement << endl;
}

View File

@ -71,6 +71,8 @@ namespace Katana {
uint32_t getRipupLimit ( uint32_t type ) const;
inline uint32_t getHTracksReservedLocal () const;
inline uint32_t getVTracksReservedLocal () const;
inline uint32_t getTermSatReservedLocal () const;
inline uint32_t getTermSatThreshold () const;
inline void setEventsLimit ( uint64_t );
inline void setRipupCost ( uint32_t );
void setRipupLimit ( uint32_t limit, uint32_t type );
@ -89,6 +91,8 @@ namespace Katana {
PostEventCb_t _postEventCb;
uint32_t _hTracksReservedLocal;
uint32_t _vTracksReservedLocal;
uint32_t _termSatReservedLocal;
uint32_t _termSatThreshold;
uint32_t _ripupLimits [RipupLimitsTableSize];
uint32_t _ripupCost;
uint64_t _eventsLimit;
@ -108,6 +112,8 @@ namespace Katana {
inline uint32_t Configuration::getRipupCost () const { return _ripupCost; }
inline uint32_t Configuration::getHTracksReservedLocal () const { return _hTracksReservedLocal; }
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::setPostEventCb ( PostEventCb_t cb ) { _postEventCb = cb; }
inline void Configuration::setEventsLimit ( uint64_t limit ) { _eventsLimit = limit; }

View File

@ -84,6 +84,8 @@ namespace Katana {
inline uint32_t getRipupCost () const;
inline uint32_t getHTracksReservedLocal () const;
inline uint32_t getVTracksReservedLocal () const;
inline uint32_t getTermSatReservedLocal () const;
inline uint32_t getTermSatThreshold () const;
inline bool profileEventCosts () const;
virtual const Name& getName () const;
inline Configuration::PostEventCb_t&
@ -183,6 +185,8 @@ namespace Katana {
inline uint32_t KatanaEngine::getRipupCost () const { return _configuration->getRipupCost(); }
inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); }
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 bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); }
inline const DataSymmetricMap& KatanaEngine::getSymmetrics () const { return _symmetrics; }

View File

@ -65,6 +65,8 @@ namespace Katana {
bool ripupPerpandiculars ( uint32_t flags=0 );
void repackPerpandiculars ( uint32_t flags );
void reprocessPerpandiculars ();
void reprocessParallels ();
bool avoidBlockage ();
bool ripple ();
bool minimize ();
bool dragMinimize ();