For merging purpose
This commit is contained in:
parent
afc3f7428a
commit
38f2b43dc8
|
@ -181,17 +181,18 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
vector<GCell*>().swap( gcells );
|
vector<GCell*>().swap( gcells );
|
||||||
|
|
||||||
DbU::Unit yprobe = getNativeMin();
|
DbU::Unit yprobe = getY();
|
||||||
GCell* gcell = getAutoSource()->getGCell();
|
GCell* gcell = getAutoSource()->getGCell();
|
||||||
GCell* end = getAutoTarget()->getGCell();
|
GCell* end = getAutoTarget()->getGCell();
|
||||||
|
|
||||||
|
cdebug_log(149,0) << "yprobe: " << DbU::getValueString(yprobe) << endl;
|
||||||
|
|
||||||
if (gcell->getXMin() > end->getXMin()) std::swap( gcell, end );
|
if (gcell->getXMin() > end->getXMin()) std::swap( gcell, end );
|
||||||
|
|
||||||
gcells.push_back( gcell );
|
gcells.push_back( gcell );
|
||||||
|
|
||||||
while ( gcell != end ) {
|
while ( gcell != end ) {
|
||||||
gcell = gcell->getEast( yprobe );
|
gcell = gcell->getEast( yprobe );
|
||||||
|
|
||||||
if (not gcell) {
|
if (not gcell) {
|
||||||
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
|
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
|
||||||
" begin:%s\n"
|
" begin:%s\n"
|
||||||
|
|
|
@ -175,10 +175,12 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
vector<GCell*>().swap( gcells );
|
vector<GCell*>().swap( gcells );
|
||||||
|
|
||||||
DbU::Unit xprobe = getNativeMin();
|
DbU::Unit xprobe = getX();
|
||||||
GCell* gcell = getAutoSource()->getGCell();
|
GCell* gcell = getAutoSource()->getGCell();
|
||||||
GCell* end = getAutoTarget()->getGCell();
|
GCell* end = getAutoTarget()->getGCell();
|
||||||
|
|
||||||
|
cdebug_log(149,0) << "xprobe: " << DbU::getValueString(xprobe) << endl;
|
||||||
|
|
||||||
if (gcell->getYMin() > end->getYMin()) std::swap( gcell, end );
|
if (gcell->getYMin() > end->getYMin()) std::swap( gcell, end );
|
||||||
|
|
||||||
gcells.push_back( gcell );
|
gcells.push_back( gcell );
|
||||||
|
@ -187,7 +189,7 @@ namespace Anabatic {
|
||||||
gcell = gcell->getNorth( xprobe );
|
gcell = gcell->getNorth( xprobe );
|
||||||
|
|
||||||
if (not gcell) {
|
if (not gcell) {
|
||||||
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
|
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
|
||||||
" begin:%s\n"
|
" begin:%s\n"
|
||||||
" end: %s"
|
" end: %s"
|
||||||
, getString(this).c_str()
|
, getString(this).c_str()
|
||||||
|
|
|
@ -64,7 +64,9 @@ namespace Anabatic {
|
||||||
|
|
||||||
string s = "<Vertex " + getString(_id)
|
string s = "<Vertex " + getString(_id)
|
||||||
+ " @(" + DbU::getValueString(_gcell->getXMin())
|
+ " @(" + DbU::getValueString(_gcell->getXMin())
|
||||||
+ "," + DbU::getValueString(_gcell->getYMin()) + ")"
|
+ "-" + DbU::getValueString(_gcell->getYMin())
|
||||||
|
+ "-" + DbU::getValueString(_gcell->getXMax())
|
||||||
|
+ "-" + DbU::getValueString(_gcell->getYMax()) + ")"
|
||||||
+ " rps:" + getString(_rpCount)
|
+ " rps:" + getString(_rpCount)
|
||||||
+ " deg:" + getString(_degree)
|
+ " deg:" + getString(_degree)
|
||||||
+ " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")
|
+ " connexId:" + ((_connexId >= 0) ? getString(_connexId) : "None")
|
||||||
|
@ -218,7 +220,7 @@ namespace Anabatic {
|
||||||
Point center = rp->getBoundingBox().getCenter();
|
Point center = rp->getBoundingBox().getCenter();
|
||||||
GCell* gcell = _anabatic->getGCellUnder( center );
|
GCell* gcell = _anabatic->getGCellUnder( center );
|
||||||
|
|
||||||
cdebug_log(112,0) << "| " << rp << endl;
|
cdebug_log(112,0) << "| " << rp << " || " << gcell << endl;
|
||||||
|
|
||||||
if (not gcell) {
|
if (not gcell) {
|
||||||
cerr << Error( "Dijkstra::load(): %s\n"
|
cerr << Error( "Dijkstra::load(): %s\n"
|
||||||
|
@ -346,6 +348,7 @@ namespace Anabatic {
|
||||||
_queue.dump();
|
_queue.dump();
|
||||||
|
|
||||||
Vertex* current = _queue.top();
|
Vertex* current = _queue.top();
|
||||||
|
cdebug_log(111,0) << "Current Vertex: " << current << endl;
|
||||||
_queue.pop();
|
_queue.pop();
|
||||||
|
|
||||||
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
|
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
|
||||||
|
|
|
@ -540,6 +540,57 @@ namespace {
|
||||||
return SouthBound;
|
return SouthBound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// Class : "SortHkByX".
|
||||||
|
|
||||||
|
class SortHkByX {
|
||||||
|
public:
|
||||||
|
inline SortHkByX ( unsigned int flags );
|
||||||
|
inline bool operator() ( Hook* h1, Hook* h2 );
|
||||||
|
protected:
|
||||||
|
unsigned int _flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline SortHkByX::SortHkByX ( unsigned int flags )
|
||||||
|
: _flags(flags)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SortHkByX::operator() ( Hook* h1, Hook* h2 )
|
||||||
|
{
|
||||||
|
DbU::Unit x1 = h1->getComponent()->getCenter().getX();
|
||||||
|
DbU::Unit x2 = h2->getComponent()->getCenter().getX();
|
||||||
|
|
||||||
|
if (x1 == x2) return false;
|
||||||
|
return (_flags & SortDecreasing) xor (x1 < x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------
|
||||||
|
// Class : "SortHkByY".
|
||||||
|
|
||||||
|
class SortHkByY {
|
||||||
|
public:
|
||||||
|
inline SortHkByY ( unsigned int flags );
|
||||||
|
inline bool operator() ( Hook* h1, Hook* h2 );
|
||||||
|
protected:
|
||||||
|
unsigned int _flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline SortHkByY::SortHkByY ( unsigned int flags )
|
||||||
|
: _flags(flags)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SortHkByY::operator() ( Hook* h1, Hook* h2 )
|
||||||
|
{
|
||||||
|
DbU::Unit y1 = h1->getComponent()->getCenter().getY();
|
||||||
|
DbU::Unit y2 = h2->getComponent()->getCenter().getY();
|
||||||
|
|
||||||
|
if (y1 == y2) return false;
|
||||||
|
return (_flags & SortDecreasing) xor (y1 < y2);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// Class : "SortRpByX".
|
// Class : "SortRpByX".
|
||||||
|
@ -658,7 +709,7 @@ namespace {
|
||||||
void _do_xG_xM2 ();
|
void _do_xG_xM2 ();
|
||||||
void _do_1G_1M3 ();
|
void _do_1G_1M3 ();
|
||||||
void _do_xG_xM3 ();
|
void _do_xG_xM3 ();
|
||||||
void _doHChannel ();
|
void _doHChannel ( ForkStack& forks );
|
||||||
void _doVChannel ();
|
void _doVChannel ();
|
||||||
void _doHStrut ();
|
void _doHStrut ();
|
||||||
void _doVStrut ();
|
void _doVStrut ();
|
||||||
|
@ -834,7 +885,9 @@ namespace {
|
||||||
Segment* fromSegment = static_cast<Segment*>( _fromHook->getComponent() );
|
Segment* fromSegment = static_cast<Segment*>( _fromHook->getComponent() );
|
||||||
_net = fromSegment->getNet();
|
_net = fromSegment->getNet();
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "For Hooks from fromHook" << endl;
|
||||||
for ( Hook* hook : fromHook->getHooks() ) {
|
for ( Hook* hook : fromHook->getHooks() ) {
|
||||||
|
cdebug_log(145,0) << "Hook: " << hook << endl;
|
||||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||||
<< "[" << (int)_connexity.fields.globals
|
<< "[" << (int)_connexity.fields.globals
|
||||||
<< "+" << (int)_connexity.fields.M1
|
<< "+" << (int)_connexity.fields.M1
|
||||||
|
@ -848,10 +901,10 @@ namespace {
|
||||||
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
|
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
|
||||||
if (toSegment) {
|
if (toSegment) {
|
||||||
switch ( getSegmentHookType(hook) ) {
|
switch ( getSegmentHookType(hook) ) {
|
||||||
case WestBound: _west = hook; break;
|
case WestBound: _west = hook; break; cdebug_log(145,0) << "hook is west";
|
||||||
case EastBound: _east = hook; break;
|
case EastBound: _east = hook; break; cdebug_log(145,0) << "hook is east";
|
||||||
case SouthBound: _south = hook; break;
|
case SouthBound: _south = hook; break; cdebug_log(145,0) << "hook is south";
|
||||||
case NorthBound: _north = hook; break;
|
case NorthBound: _north = hook; break; cdebug_log(145,0) << "hook is north";
|
||||||
}
|
}
|
||||||
|
|
||||||
_connexity.fields.globals++;
|
_connexity.fields.globals++;
|
||||||
|
@ -859,10 +912,11 @@ namespace {
|
||||||
Component* anchor = hook->getComponent();
|
Component* anchor = hook->getComponent();
|
||||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
|
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
|
||||||
|
|
||||||
cdebug_log(145,0) << "| Looking for Anchor:" << anchor << " rp:" << rp << endl;
|
cdebug_log(145,0) << "| Looking for Anchor:" << anchor << endl;
|
||||||
|
|
||||||
if (anchor) {
|
if (anchor) {
|
||||||
Contact* contact = dynamic_cast<Contact*>( anchor );
|
Contact* contact = dynamic_cast<Contact*>( anchor );
|
||||||
|
cdebug_log(145,0) << "Contact:" << contact << endl;
|
||||||
if (contact
|
if (contact
|
||||||
and ( Session::getAnabatic()->getConfiguration()->isGContact( anchor->getLayer() )
|
and ( Session::getAnabatic()->getConfiguration()->isGContact( anchor->getLayer() )
|
||||||
or Session::getAnabatic()->getConfiguration()->isGMetal ( anchor->getLayer() )) ) {
|
or Session::getAnabatic()->getConfiguration()->isGMetal ( anchor->getLayer() )) ) {
|
||||||
|
@ -880,13 +934,13 @@ namespace {
|
||||||
if (not _gcell->isMatrix()) {
|
if (not _gcell->isMatrix()) {
|
||||||
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
|
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
|
||||||
cdebug_log(145,0) << "| " << gcell << endl;
|
cdebug_log(145,0) << "| " << gcell << endl;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell())) {
|
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell())) {
|
||||||
_connexity.fields.Pad++;
|
_connexity.fields.Pad++;
|
||||||
} else {
|
} else {
|
||||||
const Layer* layer = anchor->getLayer();
|
const Layer* layer = anchor->getLayer();
|
||||||
|
cdebug_log(145,0) << "rp: " << rp << endl;
|
||||||
|
|
||||||
if (layer == Session::getRoutingLayer(0)) _connexity.fields.M1++; // M1 V
|
if (layer == Session::getRoutingLayer(0)) _connexity.fields.M1++; // M1 V
|
||||||
else if (layer == Session::getRoutingLayer(1)) _connexity.fields.M2++; // M2 H
|
else if (layer == Session::getRoutingLayer(1)) _connexity.fields.M2++; // M2 H
|
||||||
|
@ -898,7 +952,7 @@ namespace {
|
||||||
, getString(layer->getName()).c_str()
|
, getString(layer->getName()).c_str()
|
||||||
, getString(anchor).c_str() )
|
, getString(anchor).c_str() )
|
||||||
<< endl;
|
<< endl;
|
||||||
continue;
|
//continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
|
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
|
||||||
|
@ -935,6 +989,7 @@ namespace {
|
||||||
_south = NULL;
|
_south = NULL;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
cdebug_log(145,0) << " " << endl;
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
|
|
||||||
if (_gcell == NULL) throw Error( missingGCell );
|
if (_gcell == NULL) throw Error( missingGCell );
|
||||||
|
@ -1089,12 +1144,67 @@ namespace {
|
||||||
toHook->attach( master );
|
toHook->attach( master );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_gcell->isDevice ()) _doDevice();
|
if (_gcell->isDevice ()){
|
||||||
else if (_gcell->isHChannel()) _doHChannel();
|
_doDevice();
|
||||||
else if (_gcell->isVChannel()) _doVChannel();
|
cdebug_log(145,0) << "doDevice done" << endl;
|
||||||
else if (_gcell->isHStrut ()) _doHStrut();
|
if (_sourceContact) {
|
||||||
else if (_gcell->isVStrut ()) _doVStrut();
|
cdebug_log(145,0) << "sourceContact is not NULL" << endl;
|
||||||
else if (_gcell->isIoPad ()) _doIoPad();
|
AutoContact* targetContact
|
||||||
|
= ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) )
|
||||||
|
? _northEastContact : _southWestContact ;
|
||||||
|
AutoSegment* globalSegment = AutoSegment::create( _sourceContact
|
||||||
|
, targetContact
|
||||||
|
, static_cast<Segment*>( _fromHook->getComponent() )
|
||||||
|
);
|
||||||
|
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||||
|
} else {
|
||||||
|
cdebug_log(145,0) << "sourceContact is NULL" << endl;
|
||||||
|
_fromHook = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Hook* toHook = NULL;
|
||||||
|
Hook* toHookOpposite = NULL;
|
||||||
|
if ( _east and (_fromHook != _east) ) {
|
||||||
|
toHook = _east;
|
||||||
|
toHookOpposite = getSegmentOppositeHook( _east );
|
||||||
|
cdebug_log(145,0) << "Pushing East (to) " << getString(toHook) << endl;
|
||||||
|
cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl;
|
||||||
|
cdebug_log(145,0) << "Pushing East (from) " << _northEastContact << endl;
|
||||||
|
forks.push( toHookOpposite, _northEastContact );
|
||||||
|
}
|
||||||
|
if ( _west and (_fromHook != _west) ) {
|
||||||
|
toHook = _west;
|
||||||
|
toHookOpposite = getSegmentOppositeHook( _west );
|
||||||
|
cdebug_log(145,0) << "Pushing West (to) " << getString(toHook) << endl;
|
||||||
|
cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl;
|
||||||
|
cdebug_log(145,0) << "Pushing West (from) " << _southWestContact << endl;
|
||||||
|
forks.push( toHookOpposite, _southWestContact );
|
||||||
|
}
|
||||||
|
if ( _north and (_fromHook != _north) ) {
|
||||||
|
toHook = _north;
|
||||||
|
toHookOpposite = getSegmentOppositeHook( _north );
|
||||||
|
cdebug_log(145,0) << "Pushing North (to) " << getString(toHook) << endl;
|
||||||
|
cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl;
|
||||||
|
cdebug_log(145,0) << "Pushing North (from) " << _northEastContact << endl;
|
||||||
|
forks.push( toHookOpposite, _northEastContact );
|
||||||
|
}
|
||||||
|
if ( _south and (_fromHook != _south) ) {
|
||||||
|
toHook = _south;
|
||||||
|
toHookOpposite = getSegmentOppositeHook( _south );
|
||||||
|
cdebug_log(145,0) << "Pushing South (to) " << getString(toHook) << endl;
|
||||||
|
cdebug_log(145,0) << "toHookOpposite: " << toHookOpposite << endl;
|
||||||
|
cdebug_log(145,0) << "Pushing South (from) " << _southWestContact << endl;
|
||||||
|
forks.push( toHookOpposite, _southWestContact );
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ((_gcell->isHChannel()) || (_gcell->isHStrut ())){
|
||||||
|
_doHChannel( forks );
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "doHChannel done" << endl;
|
||||||
|
|
||||||
|
} else if ((_gcell->isVChannel()) || (_gcell->isVStrut ())){
|
||||||
|
_doVChannel();
|
||||||
|
} else if (_gcell->isIoPad ()) _doIoPad();
|
||||||
else
|
else
|
||||||
throw Bug( "Unmanaged GCell type: %s in %s\n"
|
throw Bug( "Unmanaged GCell type: %s in %s\n"
|
||||||
" The global routing seems to be defective."
|
" The global routing seems to be defective."
|
||||||
|
@ -1102,20 +1212,23 @@ namespace {
|
||||||
, getString(_net).c_str()
|
, getString(_net).c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
for ( Hook* toHook : _fromHook->getHooks() ) {
|
// for ( Hook* toHook : _fromHook->getHooks() ) {
|
||||||
if (toHook == _fromHook) continue;
|
// if (toHook == _fromHook) continue;
|
||||||
|
|
||||||
Segment* segment = dynamic_cast<Segment*>( toHook->getComponent() );
|
// Segment* segment = dynamic_cast<Segment*>( toHook->getComponent() );
|
||||||
if (not segment) continue;
|
// if (not segment) continue;
|
||||||
|
|
||||||
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
|
// Hook* toHookOpposite = getSegmentOppositeHook( toHook );
|
||||||
|
|
||||||
|
// // Temporary. A vector of HTee/VTee must be defined in replacement of
|
||||||
|
// // SW / NE contacts, so we connect to the right contact branch.
|
||||||
|
// cdebug_log(145,0) << "Pushing South (to) " << getString(toHook) << endl;
|
||||||
|
// cdebug_log(145,0) << "Pushing South (from) " << _southWestContact << endl;
|
||||||
|
// forks.push( toHookOpposite, _southWestContact );
|
||||||
|
// }
|
||||||
|
if (_sourceContact) {
|
||||||
|
} else _fromHook = NULL;
|
||||||
|
|
||||||
// Temporary. A vector of HTee/VTee must be defined in replacement of
|
|
||||||
// SW / NE contacts, so we connect to the right contact branch.
|
|
||||||
cdebug_log(145,0) << "Pushing South (to) " << getString(toHook) << endl;
|
|
||||||
cdebug_log(145,0) << "Pushing South (from) " << _southWestContact << endl;
|
|
||||||
forks.push( toHookOpposite, _southWestContact );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
|
@ -2094,83 +2207,253 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isVertical ( RoutingPad* rp )
|
||||||
|
{
|
||||||
|
return ( (rp->getSourcePosition().getX() == rp->getTargetPosition().getX())
|
||||||
|
&& (rp->getSourcePosition().getY() != rp->getTargetPosition().getY())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHorizontal ( RoutingPad* rp )
|
||||||
|
{
|
||||||
|
return ( (rp->getSourcePosition().getY() == rp->getTargetPosition().getY())
|
||||||
|
&& (rp->getSourcePosition().getX() != rp->getTargetPosition().getX())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
RoutingPad* returnSW ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){
|
||||||
|
|
||||||
|
DbU::Unit c1SW = (rp1->getSourcePosition().getX() - gcell->getXMin()) + (rp1->getSourcePosition().getY() - gcell->getYMin());
|
||||||
|
DbU::Unit c2SW = (rp2->getSourcePosition().getX() - gcell->getXMin()) + (rp2->getSourcePosition().getY() - gcell->getYMin());
|
||||||
|
|
||||||
|
if ( c1SW < c2SW ){
|
||||||
|
return rp1;
|
||||||
|
} else {
|
||||||
|
return rp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RoutingPad* returnNE ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){
|
||||||
|
|
||||||
|
DbU::Unit c1NE = (rp1->getTargetPosition().getX() - gcell->getXMin()) + (rp1->getTargetPosition().getY() - gcell->getYMin());
|
||||||
|
DbU::Unit c2NE = (rp2->getTargetPosition().getX() - gcell->getXMin()) + (rp2->getTargetPosition().getY() - gcell->getYMin());
|
||||||
|
|
||||||
|
if ( c1NE < c2NE ){
|
||||||
|
return rp1;
|
||||||
|
} else {
|
||||||
|
return rp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AutoContact* doRp_AC ( GCell* gcell , RoutingPad* rp, bool isSW, bool singleSeg = false )
|
||||||
|
{
|
||||||
|
const Layer* rpLayer = rp->getLayer();
|
||||||
|
size_t rpDepth = Session::getLayerDepth( rpLayer );
|
||||||
|
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
|
||||||
|
Point position;
|
||||||
|
|
||||||
|
if (singleSeg == false){
|
||||||
|
if (isSW) position = rp->getSourcePosition();
|
||||||
|
else position = rp->getTargetPosition();
|
||||||
|
} else {
|
||||||
|
position = Point ( abs(rp->getSourcePosition().getX() + rp->getTargetPosition().getX())/2
|
||||||
|
, abs(rp->getSourcePosition().getY() + rp->getTargetPosition().getY())/2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AutoContactTerminal::create( gcell
|
||||||
|
, rp
|
||||||
|
, rpLayer
|
||||||
|
, position
|
||||||
|
, viaSide, viaSide
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GCellTopology::_doDevice ()
|
void GCellTopology::_doDevice ()
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl;
|
cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl;
|
||||||
/*
|
|
||||||
// Find NE and SW routing pads
|
|
||||||
Horizontal* hne = NULL;
|
|
||||||
Vertical* vne = NULL;
|
|
||||||
Horizontal* hsw = NULL;
|
|
||||||
Vertical* vsw = NULL;
|
|
||||||
|
|
||||||
for ( Component* c : _net->getComponents() ){
|
// #0: Check if all RoutingPads are set to a component.
|
||||||
Segment* s = dynamic_cast<Segment*>(c);
|
for ( unsigned int i=0; i<_routingPads.size() ; i++ ) {
|
||||||
if (s){
|
if ( ( _routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX() )
|
||||||
if ( Session::getAnabatic()->getConfiguration()->getGContactLayer() != s->getLayer() ){
|
&&( _routingPads[i]->getSourcePosition().getY() == _routingPads[i]->getTargetPosition().getY() )
|
||||||
if ( _gcell->getBoundingBox().intersect(s->getBoundingBox() ) ){
|
){
|
||||||
Horizontal* h = dynamic_cast<Horizontal*> (s);
|
throw Error( "GCellTopology::_doDevice() Some RoutingPads are not set to a component.\n"
|
||||||
Vertical* v = dynamic_cast<Vertical*> (s);
|
" On: %s."
|
||||||
if (h){
|
, getString(_gcell).c_str()
|
||||||
if ( (not (hne)) && (not (hsw)) ){
|
);
|
||||||
hne = h;
|
}
|
||||||
hsw = h;
|
}
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "_routingPads.size(): " << _routingPads.size() << endl;
|
||||||
|
if (_routingPads.size() > 1){
|
||||||
|
// #1: Find RoutingPads to use for AutoContacts NE+SW
|
||||||
|
RoutingPad* rpNE = _routingPads[0];
|
||||||
|
RoutingPad* rpSW = _routingPads[0];
|
||||||
|
|
||||||
|
for ( unsigned int i=1 ; i<_routingPads.size() ; i++ ) {
|
||||||
|
rpNE = returnNE( _gcell, rpNE, _routingPads[i] );
|
||||||
|
rpSW = returnSW( _gcell, rpSW, _routingPads[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "rpNE: " << rpNE << endl;
|
||||||
|
cdebug_log(145,0) << "rpSW: " << rpSW << endl;
|
||||||
|
// #2: Check if 1 or 2 AutoContacts is necessary.
|
||||||
|
bool ne = false;
|
||||||
|
bool sw = false;
|
||||||
|
if ( (!_north) || (!_east) ){
|
||||||
|
_northEastContact = doRp_AC ( _gcell , rpSW, true );
|
||||||
|
ne = true;
|
||||||
|
}
|
||||||
|
if ( (!_south) || (!_west) ){
|
||||||
|
_southWestContact = doRp_AC ( _gcell , rpNE, false );
|
||||||
|
sw = true;
|
||||||
|
}
|
||||||
|
if ( ne == false ) _northEastContact = _southWestContact;
|
||||||
|
if ( sw == false ) _southWestContact = _northEastContact;
|
||||||
|
cdebug_log(145,0) << "AutoContact NE: " << _northEastContact << endl;
|
||||||
|
cdebug_log(145,0) << "AutoContact SW: " << _southWestContact << endl;
|
||||||
|
|
||||||
|
} else if (_routingPads.size() == 0){
|
||||||
|
cdebug_log(145,0) << "Pas de RoutingPad trouvé." << endl;
|
||||||
} else {
|
} else {
|
||||||
// criteria for NE: (xMax-xSegment) + (yMax-ySegment), the smaller it is, the better it is
|
// #1: Find RoutingPads to use for AutoContacts NE+SW
|
||||||
DbU::Unit bNEc = (_gcell->getXMax() - hne->getTarget()->getX()) + ( _gcell->getYMax() - hne->getTarget()->getY());
|
// Only 1 RoutingPads => 1 Component
|
||||||
DbU::Unit cNEc = (_gcell->getXMax() - h->getTarget()->getX()) + ( _gcell->getYMax() - h->getTarget()->getY() );
|
cdebug_log(145,0) << "rp: " << _routingPads[0] << endl;
|
||||||
if (cNEc < bNEc) hne = h;
|
// #2: Check if 1 or 2 AutoContacts is necessary.
|
||||||
|
bool ne = false;
|
||||||
|
bool sw = false;
|
||||||
|
|
||||||
// criteria for SW: (xSegment-xMin) + (ySegment-yMin), the smaller it is, the better it is
|
cdebug_log(145,0) << "North: " << _north << endl;
|
||||||
DbU::Unit bSWc = (hne->getSource()->getX() - _gcell->getXMin()) + (hne->getSource()->getY() - _gcell->getYMin());
|
cdebug_log(145,0) << "East : " << _east << endl;
|
||||||
DbU::Unit cSWc = (h->getSource()->getX() - _gcell->getXMin()) + (h->getSource()->getY() - _gcell->getYMin());
|
cdebug_log(145,0) << "South: " << _south << endl;
|
||||||
if (cSWc < bSWc) hsw = h;
|
cdebug_log(145,0) << "West : " << _west << endl;
|
||||||
|
if ( (_north) || (_east) ){
|
||||||
|
_northEastContact = doRp_AC ( _gcell , _routingPads[0], true );
|
||||||
|
ne = true;
|
||||||
}
|
}
|
||||||
} else if (v){
|
if ( (_south) || (_west) ){
|
||||||
if ( (not (vne)) && (not (vsw)) ){
|
_southWestContact = doRp_AC ( _gcell , _routingPads[0], false );
|
||||||
vne = v;
|
sw = true;
|
||||||
vsw = v;
|
|
||||||
} else {
|
|
||||||
// criteria for NE: (xMax-xSegment) + (yMax-ySegment), the smaller it is, the better it is
|
|
||||||
DbU::Unit bNEc = (_gcell->getXMax() - vne->getTarget()->getX()) + ( _gcell->getYMax() - vne->getTarget()->getY());
|
|
||||||
DbU::Unit cNEc = (_gcell->getXMax() - v->getTarget()->getX()) + ( _gcell->getYMax() - v->getTarget()->getY() );
|
|
||||||
if (cNEc < bNEc) vne = v;
|
|
||||||
|
|
||||||
// criteria for SW: (xSegment-xMin) + (ySegment-yMin), the smaller it is, the better it is
|
|
||||||
DbU::Unit bSWc = (vne->getSource()->getX() - _gcell->getXMin()) + (vne->getSource()->getY() - _gcell->getYMin());
|
|
||||||
DbU::Unit cSWc = (v->getSource()->getX() - _gcell->getXMin()) + (v->getSource()->getY() - _gcell->getYMin());
|
|
||||||
if (cSWc < bSWc) vsw = v;
|
|
||||||
}
|
}
|
||||||
|
if ( ne == false ) _northEastContact = _southWestContact;
|
||||||
|
if ( sw == false ) _southWestContact = _northEastContact;
|
||||||
|
cdebug_log(145,0) << "AutoContact NE: " << _northEastContact << endl;
|
||||||
|
cdebug_log(145,0) << "AutoContact SW: " << _southWestContact << endl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// SetExternal + create AutoContact northEast + southWest, Placed center of segment
|
|
||||||
if (hne) cerr << "NE: " << hne << endl;
|
|
||||||
else cerr << "NE: " << vne << endl;
|
|
||||||
|
|
||||||
if (hsw) cerr << "SW: " << hsw << endl;
|
|
||||||
else cerr << "SW: " << vsw << endl;
|
|
||||||
*/
|
|
||||||
/*problem: How to create routing pad with segment only without plugs
|
|
||||||
*/
|
|
||||||
|
|
||||||
// _north, _south, _west, _east => segment GContact
|
|
||||||
// if nort or east
|
|
||||||
// detach wire from GContact to AutoContact
|
|
||||||
// move Segment to wire X (vertical), Y (horizontal) given by AutoContact
|
|
||||||
// do accordingly for _south and _west
|
|
||||||
|
|
||||||
//throw Error( "GCellTopology::_doDevice() Unimplemented, blame goes to E. Lao." );
|
|
||||||
|
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GCellTopology::_doHChannel ()
|
void GCellTopology::_doHChannel ( ForkStack& forks )
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "void GCellTopology::_doHChannel ()" << _gcell << endl;
|
cdebug_log(145,1) << "void GCellTopology::_doHChannel ( ForkStack& forks )" << _gcell << endl;
|
||||||
|
|
||||||
|
vector<Hook*> hooks;
|
||||||
|
vector<AutoContact*> autoContacts;
|
||||||
|
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "fromHook: " << _fromHook << endl;
|
||||||
|
for ( Hook* toHook : _fromHook->getHooks() ) {
|
||||||
|
cdebug_log(145,0) << "toHook: " << toHook << endl;
|
||||||
|
|
||||||
|
Segment* s = dynamic_cast<Segment*>( toHook->getComponent() );
|
||||||
|
if (s) hooks.push_back(toHook);
|
||||||
|
}
|
||||||
|
|
||||||
|
sort( hooks.begin(), hooks.end(), SortHkByX(NoFlags) );
|
||||||
|
size_t i = 0;
|
||||||
|
for (vector<Hook*>::iterator it = hooks.begin(); it != hooks.end(); it++){
|
||||||
|
|
||||||
|
Horizontal* h = dynamic_cast<Horizontal*>((*it)->getComponent());
|
||||||
|
Vertical* v = dynamic_cast<Vertical*> ((*it)->getComponent());
|
||||||
|
AutoContact* ac = NULL;
|
||||||
|
if (i == 0){
|
||||||
|
if (h){
|
||||||
|
ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) );
|
||||||
|
ac->setX(_gcell->getXMin());
|
||||||
|
ac->setY(_gcell->getYMin() + _gcell->getHeight()/2);
|
||||||
|
} else if (v){
|
||||||
|
ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
|
||||||
|
ac->setX(v->getX());
|
||||||
|
ac->setY(_gcell->getYMin() + _gcell->getHeight()/2);
|
||||||
|
}
|
||||||
|
} else if (i == hooks.size()-1){
|
||||||
|
if (h){
|
||||||
|
ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) );
|
||||||
|
ac->setX(_gcell->getXMin() + _gcell->getWidth());
|
||||||
|
ac->setY(_gcell->getYMin() + _gcell->getHeight()/2);
|
||||||
|
} else if (v){
|
||||||
|
ac = AutoContactTurn::create( _gcell, _net, Session::getContactLayer(1) );
|
||||||
|
ac->setX(v->getX());
|
||||||
|
ac->setY(_gcell->getYMin() + _gcell->getHeight()/2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ac = AutoContactHTee::create( _gcell, _net, Session::getContactLayer(2) );
|
||||||
|
ac->setX(v->getX());
|
||||||
|
ac->setY(_gcell->getYMin() + _gcell->getHeight()/2);
|
||||||
|
}
|
||||||
|
autoContacts.push_back(ac);
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "FromHook: " << _fromHook << endl << endl;
|
||||||
|
if (_fromHook->getComponent() == (*it)->getComponent()){
|
||||||
|
cdebug_log(145,0) << "Found from:" << (*it)->getComponent() << endl;
|
||||||
|
|
||||||
|
if (_sourceContact) {
|
||||||
|
|
||||||
|
if ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) ){
|
||||||
|
AutoSegment* globalSegment = AutoSegment::create( ac
|
||||||
|
, _sourceContact
|
||||||
|
, static_cast<Segment*>( _fromHook->getComponent() )
|
||||||
|
);
|
||||||
|
globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 );
|
||||||
|
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||||
|
} else if ( getSegmentHookType(_fromHook) & (EastBound|SouthBound) ){
|
||||||
|
AutoSegment* globalSegment = AutoSegment::create( ac
|
||||||
|
, _sourceContact
|
||||||
|
, static_cast<Segment*>( _fromHook->getComponent() )
|
||||||
|
);
|
||||||
|
globalSegment->setFlags( (_degree == 2) ? SegBipoint : 0 );
|
||||||
|
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||||
|
}
|
||||||
|
} else _fromHook = NULL;
|
||||||
|
} else {
|
||||||
|
forks.push( getSegmentOppositeHook((*it)), ac );
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "Segments:" << hooks.size() <<endl;
|
||||||
|
for (vector<Hook*>::iterator it = hooks.begin(); it != hooks.end(); it++){
|
||||||
|
cdebug_log(145,0) << (*it)->getComponent() << endl;
|
||||||
|
}
|
||||||
|
cdebug_log(145,0) << "AutoContacts:" << autoContacts.size() << endl;
|
||||||
|
static const Layer* hLayer = Session::getRoutingLayer( 1 );
|
||||||
|
static DbU::Unit hWidth = Session::getWireWidth ( 1 );
|
||||||
|
const Layer* horizontalLayer = hLayer;
|
||||||
|
DbU::Unit horizontalWidth = hWidth;
|
||||||
|
|
||||||
|
for (size_t j=1; j < autoContacts.size(); j++){
|
||||||
|
AutoSegment::create( autoContacts[j-1]
|
||||||
|
, autoContacts[j]
|
||||||
|
, Horizontal::create( autoContacts[j-1]->base()
|
||||||
|
, autoContacts[j]->base()
|
||||||
|
, horizontalLayer
|
||||||
|
, autoContacts[j-1]->getY()
|
||||||
|
, horizontalWidth
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (vector<AutoContact*>::iterator it = autoContacts.begin(); it != autoContacts.end(); it++){
|
||||||
|
cdebug_log(145,0) << (*it) << endl;
|
||||||
|
}
|
||||||
|
cdebug_log(145,0) << _sourceContact << endl;
|
||||||
|
|
||||||
/*throw Error( "GCellTopology::_doHChannel() Unimplemented, blame goes to E. Lao.\n"
|
/*throw Error( "GCellTopology::_doHChannel() Unimplemented, blame goes to E. Lao.\n"
|
||||||
" On: %s."
|
" On: %s."
|
||||||
|
@ -2263,7 +2546,7 @@ namespace Anabatic {
|
||||||
|
|
||||||
void AnabaticEngine::_loadNetGlobalRouting ( Net* net )
|
void AnabaticEngine::_loadNetGlobalRouting ( Net* net )
|
||||||
{
|
{
|
||||||
cdebug_log(149,0) << "Anabatic::_loadNetGlobalRouting( " << net << " )" << endl;
|
cdebug_log(149,0) << "Anabatic::_loadNetGlobalRouting( " << net << " ) ==========================================================" << endl;
|
||||||
cdebug_tabw(145,1);
|
cdebug_tabw(145,1);
|
||||||
|
|
||||||
ForkStack forks;
|
ForkStack forks;
|
||||||
|
@ -2303,6 +2586,7 @@ namespace Anabatic {
|
||||||
forEach ( RoutingPad*, startRp, routingPads ) {
|
forEach ( RoutingPad*, startRp, routingPads ) {
|
||||||
bool segmentFound = false;
|
bool segmentFound = false;
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "startRp: " << startRp << endl;
|
||||||
forEach ( Hook*, ihook, startRp->getBodyHook()->getHooks() ) {
|
forEach ( Hook*, ihook, startRp->getBodyHook()->getHooks() ) {
|
||||||
cdebug_log(145,0) << "Component " << ihook->getComponent() << endl;
|
cdebug_log(145,0) << "Component " << ihook->getComponent() << endl;
|
||||||
Segment* segment = dynamic_cast<Segment*>( ihook->getComponent() );
|
Segment* segment = dynamic_cast<Segment*>( ihook->getComponent() );
|
||||||
|
@ -2312,6 +2596,7 @@ namespace Anabatic {
|
||||||
segmentFound = true;
|
segmentFound = true;
|
||||||
|
|
||||||
GCellTopology gcellConf ( this, *ihook, NULL );
|
GCellTopology gcellConf ( this, *ihook, NULL );
|
||||||
|
cdebug_log(145,0) << "GCell.globals: " << gcellConf.getStateG() << endl;
|
||||||
if (gcellConf.getStateG() == 1) {
|
if (gcellConf.getStateG() == 1) {
|
||||||
if ( (lowestGCell == NULL) or (*gcellConf.getGCell() < *lowestGCell) ) {
|
if ( (lowestGCell == NULL) or (*gcellConf.getGCell() < *lowestGCell) ) {
|
||||||
cdebug_log(145,0) << "Starting from GCell " << gcellConf.getGCell() << endl;
|
cdebug_log(145,0) << "Starting from GCell " << gcellConf.getGCell() << endl;
|
||||||
|
@ -2341,7 +2626,9 @@ namespace Anabatic {
|
||||||
|
|
||||||
if (startHook == NULL) { singleGCell( this, net ); cdebug_tabw(145,-1); return; }
|
if (startHook == NULL) { singleGCell( this, net ); cdebug_tabw(145,-1); return; }
|
||||||
|
|
||||||
|
cdebug_log(145,0) << "******************************" << endl;
|
||||||
GCellTopology startGCellConf ( this, startHook, NULL );
|
GCellTopology startGCellConf ( this, startHook, NULL );
|
||||||
|
cdebug_log(145,0) << "StartGCellConf" << startGCellConf.getGCell() << endl;
|
||||||
startGCellConf.construct( forks );
|
startGCellConf.construct( forks );
|
||||||
|
|
||||||
sourceHook = forks.getFrom ();
|
sourceHook = forks.getFrom ();
|
||||||
|
|
|
@ -187,6 +187,8 @@ namespace Anabatic {
|
||||||
void setXY ( DbU::Unit x, DbU::Unit y );
|
void setXY ( DbU::Unit x, DbU::Unit y );
|
||||||
void updateContactsPosition ();
|
void updateContactsPosition ();
|
||||||
void cleanupGlobal ();
|
void cleanupGlobal ();
|
||||||
|
inline DbU::Unit getWidth () const;
|
||||||
|
inline DbU::Unit getHeight () const;
|
||||||
// Detailed routing functions.
|
// Detailed routing functions.
|
||||||
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;
|
||||||
|
@ -328,6 +330,10 @@ namespace Anabatic {
|
||||||
inline const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
inline 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; }
|
||||||
|
|
||||||
|
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
|
||||||
|
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
|
||||||
|
|
||||||
inline const GCell::Key& GCell::getKey () const { return _key; }
|
inline const GCell::Key& GCell::getKey () const { return _key; }
|
||||||
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
|
||||||
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
|
||||||
|
|
Loading…
Reference in New Issue