Redesigning access to analog terminals in devices.
* New: In Anabatic::AutoContact, added forceOnGrid() method to allow a AutoContactTerminal to be set (and fixed) outside it's constraint Box. Be aware that this may generate gaps in the routing. Stored using the UserNativeConstraints mechanism. * New: In Anabatic::Session() new method getNearestgridpoint() to easily compute the nearest grid point from a position. * Change: In Anabatic::AutoSegment::_revalidate(), use layer mask to compute the spin of the segment instead of the layers (more robust for analogic). * New: In ::GCellTopology::doRp_Access() new method to create terminal contacts in _doDevice(). Issue more warnings and force the terminal to on grid (even if it create gaps). This a temporary hack.
This commit is contained in:
parent
47c9961ef3
commit
dc46340d6a
|
@ -385,6 +385,16 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AutoContact::forceOnGrid ( Point )
|
||||||
|
{
|
||||||
|
cerr << Warning( "AutoContact::forcedOnGrid() not implemented for this derived class.\n"
|
||||||
|
" %s\n"
|
||||||
|
, getString(this).c_str()
|
||||||
|
) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool AutoContact::isTee ( unsigned int direction ) const
|
bool AutoContact::isTee ( unsigned int direction ) const
|
||||||
{
|
{
|
||||||
return (isHTee() and (direction & Flags::Horizontal))
|
return (isHTee() and (direction & Flags::Horizontal))
|
||||||
|
|
|
@ -145,6 +145,12 @@ namespace Anabatic {
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "AutoContactTerminal::getNativeConstraintBox()" << endl;
|
cdebug_log(145,1) << "AutoContactTerminal::getNativeConstraintBox()" << endl;
|
||||||
|
|
||||||
|
if (isUserNativeConstraints()) {
|
||||||
|
cdebug_log(145,1) << " Native constraints sets by user:" << getConstraintBox() << endl;
|
||||||
|
cdebug_tabw(145,-1);
|
||||||
|
return getConstraintBox();
|
||||||
|
}
|
||||||
|
|
||||||
Component* component = getAnchor();
|
Component* component = getAnchor();
|
||||||
if (component == NULL) {
|
if (component == NULL) {
|
||||||
cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl;
|
cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl;
|
||||||
|
@ -224,7 +230,8 @@ namespace Anabatic {
|
||||||
order( xMin, xMax );
|
order( xMin, xMax );
|
||||||
order( yMin, yMax );
|
order( yMin, yMax );
|
||||||
|
|
||||||
cdebug_log(145,0) << "| Using (y): " << DbU::getValueString(yMin) << " "
|
cdebug_log(145,0) << "| Using (y): "
|
||||||
|
<< DbU::getValueString(yMin) << " "
|
||||||
<< DbU::getValueString(yMax) << endl;
|
<< DbU::getValueString(yMax) << endl;
|
||||||
|
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
|
@ -405,6 +412,13 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AutoContactTerminal::forceOnGrid ( Point gridPoint )
|
||||||
|
{
|
||||||
|
setFlags( CntUserNativeConstraints );
|
||||||
|
setConstraintBox( Box(gridPoint) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string AutoContactTerminal::_getTypeName () const
|
string AutoContactTerminal::_getTypeName () const
|
||||||
{ return "ContactTerminal"; }
|
{ return "ContactTerminal"; }
|
||||||
|
|
||||||
|
|
|
@ -472,7 +472,7 @@ namespace Anabatic {
|
||||||
cdebug_log(149,0) << "Changed source: " << source << endl;
|
cdebug_log(149,0) << "Changed source: " << source << endl;
|
||||||
|
|
||||||
unsetFlags( SegSourceTop|SegSourceBottom );
|
unsetFlags( SegSourceTop|SegSourceBottom );
|
||||||
if (contactLayer != segmentLayer)
|
if (contactLayer->getMask() != segmentLayer->getMask())
|
||||||
setFlags( (segmentLayer == contactLayer->getTop()) ? SegSourceBottom : SegSourceTop );
|
setFlags( (segmentLayer == contactLayer->getTop()) ? SegSourceBottom : SegSourceTop );
|
||||||
if (source->isTurn() and source->getPerpandicular(this)->isReduced())
|
if (source->isTurn() and source->getPerpandicular(this)->isReduced())
|
||||||
incReduceds();
|
incReduceds();
|
||||||
|
@ -485,7 +485,7 @@ namespace Anabatic {
|
||||||
cdebug_log(149,0) << "Changed target: " << target << endl;
|
cdebug_log(149,0) << "Changed target: " << target << endl;
|
||||||
|
|
||||||
unsetFlags( SegTargetTop|SegTargetBottom );
|
unsetFlags( SegTargetTop|SegTargetBottom );
|
||||||
if (contactLayer != segmentLayer)
|
if (contactLayer->getMask() != segmentLayer->getMask())
|
||||||
setFlags( (segmentLayer == contactLayer->getTop()) ? SegTargetBottom : SegTargetTop );
|
setFlags( (segmentLayer == contactLayer->getTop()) ? SegTargetBottom : SegTargetTop );
|
||||||
if (target->isTurn() and target->getPerpandicular(this)->isReduced())
|
if (target->isTurn() and target->getPerpandicular(this)->isReduced())
|
||||||
incReduceds();
|
incReduceds();
|
||||||
|
@ -1971,11 +1971,11 @@ namespace Anabatic {
|
||||||
state += isReduced () ? "r": "-";
|
state += isReduced () ? "r": "-";
|
||||||
state += isInvalidated () ? "i": "-";
|
state += isInvalidated () ? "i": "-";
|
||||||
|
|
||||||
if (_flags & SegSourceTop) state += 'T';
|
if (_flags & SegSourceTop) state += 't';
|
||||||
else if (_flags & SegSourceBottom) state += 'B';
|
else if (_flags & SegSourceBottom) state += 'b';
|
||||||
else state += '-';
|
else state += '-';
|
||||||
if (_flags & SegTargetTop) state += 'T';
|
if (_flags & SegTargetTop) state += 't';
|
||||||
else if (_flags & SegTargetBottom) state += 'B';
|
else if (_flags & SegTargetBottom) state += 'b';
|
||||||
else state += '-';
|
else state += '-';
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -697,6 +697,7 @@ namespace {
|
||||||
static void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, unsigned int flags );
|
static void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, unsigned int flags );
|
||||||
static AutoContact* doRp_Access ( GCell*, Component*, unsigned int flags );
|
static AutoContact* doRp_Access ( GCell*, Component*, unsigned int flags );
|
||||||
static AutoContact* doRp_AccessPad ( RoutingPad*, unsigned int flags );
|
static AutoContact* doRp_AccessPad ( RoutingPad*, unsigned int flags );
|
||||||
|
static AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, unsigned int flags );
|
||||||
static void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 );
|
static void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 );
|
||||||
static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 );
|
static void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 );
|
||||||
private:
|
private:
|
||||||
|
@ -1448,6 +1449,42 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AutoContact* GCellTopology::doRp_AccessAnalog ( GCell* gcell, RoutingPad* rp, unsigned int flags )
|
||||||
|
{
|
||||||
|
cdebug_log(145,1) << "doRp_AccessAnalog()" << endl;
|
||||||
|
cdebug_log(145,0) << rp << endl;
|
||||||
|
|
||||||
|
const Layer* rpLayer = rp->getLayer();
|
||||||
|
size_t rpDepth = Session::getLayerDepth( rpLayer );
|
||||||
|
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
|
||||||
|
Point position = rp->getCenter();
|
||||||
|
Point onGrid = Session::getNearestGridPoint( position, gcell->getConstraintBox() );
|
||||||
|
|
||||||
|
AutoContact* contact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide );
|
||||||
|
|
||||||
|
if (position != onGrid) {
|
||||||
|
cerr << Bug( "GCellTopology::doRp_AccessAnalog(): RoutingPad is not under any grid point.\n"
|
||||||
|
" %s\n"
|
||||||
|
" Using nearest grid point: %s"
|
||||||
|
, getString(rp).c_str()
|
||||||
|
, getString(onGrid).c_str()
|
||||||
|
) << endl;
|
||||||
|
contact->forceOnGrid( onGrid );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rpDepth != 1) {
|
||||||
|
cerr << Bug( "GCellTopology::doRp_AccessAnalog(): RoutingPad must be in METAL2 layer.\n"
|
||||||
|
" %s"
|
||||||
|
, getString(rp).c_str()
|
||||||
|
) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdebug_log(145,0) << contact << endl;
|
||||||
|
cdebug_tabw(145,-1);
|
||||||
|
return contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GCellTopology::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 )
|
void GCellTopology::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 )
|
||||||
{
|
{
|
||||||
cdebug_log(145,0) << "doRp_StairCaseH()" << endl;
|
cdebug_log(145,0) << "doRp_StairCaseH()" << endl;
|
||||||
|
@ -2157,6 +2194,7 @@ namespace {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isHorizontal ( RoutingPad* rp )
|
bool isHorizontal ( RoutingPad* rp )
|
||||||
{
|
{
|
||||||
return ( (rp->getSourcePosition().getY() == rp->getTargetPosition().getY())
|
return ( (rp->getSourcePosition().getY() == rp->getTargetPosition().getY())
|
||||||
|
@ -2164,8 +2202,9 @@ namespace {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
RoutingPad* returnSW ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){
|
|
||||||
|
|
||||||
|
RoutingPad* returnSW ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 )
|
||||||
|
{
|
||||||
DbU::Unit c1SW = (rp1->getSourcePosition().getX() - gcell->getXMin()) + (rp1->getSourcePosition().getY() - gcell->getYMin());
|
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());
|
DbU::Unit c2SW = (rp2->getSourcePosition().getX() - gcell->getXMin()) + (rp2->getSourcePosition().getY() - gcell->getYMin());
|
||||||
|
|
||||||
|
@ -2176,8 +2215,9 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RoutingPad* returnNE ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ){
|
|
||||||
|
|
||||||
|
RoutingPad* returnNE ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 )
|
||||||
|
{
|
||||||
DbU::Unit c1NE = (gcell->getXMax() - rp1->getTargetPosition().getX()) + (gcell->getYMax() - rp1->getTargetPosition().getY());
|
DbU::Unit c1NE = (gcell->getXMax() - rp1->getTargetPosition().getX()) + (gcell->getYMax() - rp1->getTargetPosition().getY());
|
||||||
DbU::Unit c2NE = (gcell->getXMax() - rp2->getTargetPosition().getX()) + (gcell->getYMax() - rp2->getTargetPosition().getY());
|
DbU::Unit c2NE = (gcell->getXMax() - rp2->getTargetPosition().getX()) + (gcell->getYMax() - rp2->getTargetPosition().getY());
|
||||||
|
|
||||||
|
@ -2189,31 +2229,6 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AutoContact* GCellTopology::_doDevice ( ForkStack& forks )
|
AutoContact* GCellTopology::_doDevice ( ForkStack& forks )
|
||||||
{
|
{
|
||||||
cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl;
|
cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl;
|
||||||
|
@ -2272,69 +2287,25 @@ namespace {
|
||||||
if ((rpNE != NULL) && (rpSW != NULL)){
|
if ((rpNE != NULL) && (rpSW != NULL)){
|
||||||
if (_east){
|
if (_east){
|
||||||
cdebug_log(145,0) << "East" << endl;
|
cdebug_log(145,0) << "East" << endl;
|
||||||
const Layer* rpLayer = rpNE->getLayer();
|
AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags );
|
||||||
size_t rpDepth = Session::getLayerDepth( rpLayer );
|
|
||||||
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
|
|
||||||
Point position;
|
|
||||||
|
|
||||||
position = Point ( abs(rpNE->getSourcePosition().getX() + rpNE->getTargetPosition().getX())/2
|
|
||||||
, abs(rpNE->getSourcePosition().getY() + rpNE->getTargetPosition().getY())/2
|
|
||||||
);
|
|
||||||
AutoContact* ac = AutoContactTerminal::create( _gcell, rpNE, rpLayer, position
|
|
||||||
, viaSide, viaSide
|
|
||||||
);
|
|
||||||
cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl;
|
|
||||||
if ( _fromHook != _east) forks.push( getSegmentOppositeHook( _east ), ac );
|
if ( _fromHook != _east) forks.push( getSegmentOppositeHook( _east ), ac );
|
||||||
else targetContact = ac;
|
else targetContact = ac;
|
||||||
}
|
}
|
||||||
if (_west){
|
if (_west){
|
||||||
cdebug_log(145,0) << "West" << endl;
|
cdebug_log(145,0) << "West" << endl;
|
||||||
const Layer* rpLayer = rpSW->getLayer();
|
AutoContact* ac = doRp_AccessAnalog( _gcell, rpSW, NoFlags );
|
||||||
size_t rpDepth = Session::getLayerDepth( rpLayer );
|
|
||||||
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
|
|
||||||
Point position;
|
|
||||||
|
|
||||||
position = Point ( abs(rpSW->getSourcePosition().getX() + rpSW->getTargetPosition().getX())/2
|
|
||||||
, abs(rpSW->getSourcePosition().getY() + rpSW->getTargetPosition().getY())/2
|
|
||||||
);
|
|
||||||
AutoContact* ac = AutoContactTerminal::create( _gcell, rpSW, rpLayer, position
|
|
||||||
, viaSide, viaSide
|
|
||||||
);
|
|
||||||
cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl;
|
|
||||||
if ( _fromHook != _west) forks.push( getSegmentOppositeHook( _west ), ac );
|
if ( _fromHook != _west) forks.push( getSegmentOppositeHook( _west ), ac );
|
||||||
else targetContact = ac;
|
else targetContact = ac;
|
||||||
}
|
}
|
||||||
if (_south){
|
if (_south){
|
||||||
cdebug_log(145,0) << "South" << endl;
|
cdebug_log(145,0) << "South" << endl;
|
||||||
const Layer* rpLayer = rpSW->getLayer();
|
AutoContact* ac = doRp_AccessAnalog( _gcell, rpSW, NoFlags );
|
||||||
size_t rpDepth = Session::getLayerDepth( rpLayer );
|
|
||||||
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
|
|
||||||
Point position;
|
|
||||||
|
|
||||||
position = Point ( abs(rpSW->getSourcePosition().getX() + rpSW->getTargetPosition().getX())/2
|
|
||||||
, abs(rpSW->getSourcePosition().getY() + rpSW->getTargetPosition().getY())/2
|
|
||||||
);
|
|
||||||
AutoContact* ac = AutoContactTerminal::create( _gcell, rpSW, rpLayer, position
|
|
||||||
, viaSide, viaSide
|
|
||||||
);
|
|
||||||
cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl;
|
|
||||||
if ( _fromHook != _south) forks.push( getSegmentOppositeHook( _south ), ac );
|
if ( _fromHook != _south) forks.push( getSegmentOppositeHook( _south ), ac );
|
||||||
else targetContact = ac;
|
else targetContact = ac;
|
||||||
}
|
}
|
||||||
if (_north){
|
if (_north){
|
||||||
cdebug_log(145,0) << "North" << endl;
|
cdebug_log(145,0) << "North" << endl;
|
||||||
const Layer* rpLayer = rpNE->getLayer();
|
AutoContact* ac = doRp_AccessAnalog( _gcell, rpNE, NoFlags );
|
||||||
size_t rpDepth = Session::getLayerDepth( rpLayer );
|
|
||||||
DbU::Unit viaSide = Session::getWireWidth ( rpDepth );
|
|
||||||
Point position;
|
|
||||||
|
|
||||||
position = Point ( abs(rpNE->getSourcePosition().getX() + rpNE->getTargetPosition().getX())/2
|
|
||||||
, abs(rpNE->getSourcePosition().getY() + rpNE->getTargetPosition().getY())/2
|
|
||||||
);
|
|
||||||
AutoContact* ac = AutoContactTerminal::create( _gcell, rpNE, rpLayer, position
|
|
||||||
, viaSide, viaSide
|
|
||||||
);
|
|
||||||
cdebug_log(145,0) << "[Create AutoContact]: " << ac << endl;
|
|
||||||
if ( _fromHook != _north) forks.push( getSegmentOppositeHook( _north ), ac );
|
if ( _fromHook != _north) forks.push( getSegmentOppositeHook( _north ), ac );
|
||||||
else targetContact = ac;
|
else targetContact = ac;
|
||||||
}
|
}
|
||||||
|
@ -2343,104 +2314,6 @@ namespace {
|
||||||
cdebug_tabw(145,-1);
|
cdebug_tabw(145,-1);
|
||||||
return targetContact;
|
return targetContact;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
AutoContact* GCellTopology::_doDevice ( ForkStack& forks )
|
|
||||||
{
|
|
||||||
cdebug_log(145,1) << "void GCellTopology::_doDevice ()" << _gcell << endl;
|
|
||||||
// #0: Check if all RoutingPads are set to a component.
|
|
||||||
for ( unsigned int i=0; i<_routingPads.size() ; i++ ) {
|
|
||||||
if ( ( _routingPads[i]->getSourcePosition().getX() == _routingPads[i]->getTargetPosition().getX() )
|
|
||||||
&&( _routingPads[i]->getSourcePosition().getY() == _routingPads[i]->getTargetPosition().getY() )
|
|
||||||
){
|
|
||||||
throw Error( "GCellTopology::_doDevice() Some RoutingPads are not set to a component.\n"
|
|
||||||
" On: %s."
|
|
||||||
, getString(_gcell).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
// #1: Find RoutingPads to use for AutoContacts NE+SW
|
|
||||||
// Only 1 RoutingPads => 1 Component
|
|
||||||
cdebug_log(145,0) << "rp: " << _routingPads[0] << endl;
|
|
||||||
// #2: Check if 1 or 2 AutoContacts is necessary.
|
|
||||||
bool ne = false;
|
|
||||||
bool sw = false;
|
|
||||||
|
|
||||||
if ( (_north) || (_east) ){
|
|
||||||
_northEastContact = doRp_AC ( _gcell , _routingPads[0], true );
|
|
||||||
ne = true;
|
|
||||||
}
|
|
||||||
if ( (_south) || (_west) ){
|
|
||||||
_southWestContact = doRp_AC ( _gcell , _routingPads[0], 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoContact* targetContact = NULL;
|
|
||||||
if (_sourceContact){
|
|
||||||
targetContact = ( getSegmentHookType(_fromHook) & (NorthBound|EastBound) )
|
|
||||||
? _northEastContact : _southWestContact ;
|
|
||||||
}
|
|
||||||
cdebug_log(145,0) << "fromHook: " << _fromHook << endl;
|
|
||||||
cdebug_log(145,0) << "North : " << _north << endl;
|
|
||||||
cdebug_log(145,0) << "East : " << _east << endl;
|
|
||||||
cdebug_log(145,0) << "South : " << _south << endl;
|
|
||||||
cdebug_log(145,0) << "West : " << _west << endl;
|
|
||||||
|
|
||||||
if ( _east and (_fromHook != _east) ) {
|
|
||||||
forks.push( getSegmentOppositeHook( _east ), _northEastContact );
|
|
||||||
}
|
|
||||||
if ( _west and (_fromHook != _west) ) {
|
|
||||||
forks.push( getSegmentOppositeHook( _west ), _southWestContact );
|
|
||||||
}
|
|
||||||
if ( _north and (_fromHook != _north) ) {
|
|
||||||
forks.push( getSegmentOppositeHook( _north ), _northEastContact );
|
|
||||||
}
|
|
||||||
if ( _south and (_fromHook != _south) ) {
|
|
||||||
forks.push( getSegmentOppositeHook( _south ), _southWestContact );
|
|
||||||
}
|
|
||||||
|
|
||||||
cdebug_log(145,0) << "doDevice done" << endl;
|
|
||||||
cdebug_tabw(145,-1);
|
|
||||||
|
|
||||||
return targetContact;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
AutoContact* GCellTopology::_doHChannel ( ForkStack& forks )
|
AutoContact* GCellTopology::_doHChannel ( ForkStack& forks )
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "hurricane/Cell.h"
|
#include "hurricane/Cell.h"
|
||||||
#include "hurricane/UpdateSession.h"
|
#include "hurricane/UpdateSession.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
|
#include "crlcore/RoutingLayerGauge.h"
|
||||||
#include "anabatic/Configuration.h"
|
#include "anabatic/Configuration.h"
|
||||||
#include "anabatic/Session.h"
|
#include "anabatic/Session.h"
|
||||||
#include "anabatic/AutoContact.h"
|
#include "anabatic/AutoContact.h"
|
||||||
|
@ -51,6 +52,7 @@ namespace Anabatic {
|
||||||
using Hurricane::Horizontal;
|
using Hurricane::Horizontal;
|
||||||
using Hurricane::Vertical;
|
using Hurricane::Vertical;
|
||||||
using Hurricane::Cell;
|
using Hurricane::Cell;
|
||||||
|
using CRL::RoutingLayerGauge;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -336,6 +338,32 @@ namespace Anabatic {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Point Session::_getNearestGridPoint ( Point p, Box constraint )
|
||||||
|
{
|
||||||
|
Box ab = _anabatic->getCell()->getAbutmentBox();
|
||||||
|
|
||||||
|
RoutingLayerGauge* lg = _routingGauge->getLayerGauge( 1 );
|
||||||
|
DbU::Unit x = lg->getTrackPosition( ab.getXMin()
|
||||||
|
, lg->getTrackIndex( ab.getXMin()
|
||||||
|
, ab.getXMax()
|
||||||
|
, p.getX()
|
||||||
|
, Constant::Nearest ) );
|
||||||
|
if (x < constraint.getXMin()) x += lg->getPitch();
|
||||||
|
if (x > constraint.getXMax()) x -= lg->getPitch();
|
||||||
|
|
||||||
|
lg = _routingGauge->getLayerGauge( 2 );
|
||||||
|
DbU::Unit y = lg->getTrackPosition( ab.getYMin()
|
||||||
|
, lg->getTrackIndex( ab.getYMin()
|
||||||
|
, ab.getYMax()
|
||||||
|
, p.getY()
|
||||||
|
, Constant::Nearest ) );
|
||||||
|
if (y < constraint.getYMin()) y += lg->getPitch();
|
||||||
|
if (y > constraint.getYMax()) y -= lg->getPitch();
|
||||||
|
|
||||||
|
return Point(x,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Session::isInDemoMode ()
|
bool Session::isInDemoMode ()
|
||||||
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
|
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
|
||||||
|
|
||||||
|
|
|
@ -52,18 +52,18 @@ namespace Anabatic {
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Class : "Anabatic::AutoContact".
|
// Class : "Anabatic::AutoContact".
|
||||||
|
|
||||||
enum AutoContactFlag { CntFixed = 0x00000001
|
enum AutoContactFlag { CntFixed = (1 << 0)
|
||||||
, CntTerminal = 0x00000002
|
, CntTerminal = (1 << 1)
|
||||||
, CntTurn = 0x00000004
|
, CntTurn = (1 << 2)
|
||||||
, CntHTee = 0x00000008
|
, CntHTee = (1 << 3)
|
||||||
, CntVTee = 0x00000010
|
, CntVTee = (1 << 4)
|
||||||
, CntInvalidated = 0x00000020
|
, CntInvalidated = (1 << 6)
|
||||||
, CntInvalidatedCache = 0x00000040
|
, CntInvalidatedCache = (1 << 7)
|
||||||
, CntInCreationStage = 0x00000080
|
, CntInCreationStage = (1 << 8)
|
||||||
, CntBadTopology = 0x00000100
|
, CntBadTopology = (1 << 9)
|
||||||
, CntIgnoreAnchor = 0x00000200
|
, CntIgnoreAnchor = (1 << 10)
|
||||||
, CntWeakTerminal = 0x00000400
|
, CntWeakTerminal = (1 << 11)
|
||||||
, CntUserNativeConstraints = 0x00000800
|
, CntUserNativeConstraints = (1 << 12)
|
||||||
};
|
};
|
||||||
|
|
||||||
class AutoContact {
|
class AutoContact {
|
||||||
|
@ -149,6 +149,7 @@ namespace Anabatic {
|
||||||
virtual void updateTopology () = 0;
|
virtual void updateTopology () = 0;
|
||||||
void showTopologyError ( const std::string&, unsigned int flags=0 );
|
void showTopologyError ( const std::string&, unsigned int flags=0 );
|
||||||
virtual void checkTopology ();
|
virtual void checkTopology ();
|
||||||
|
virtual void forceOnGrid ( Point );
|
||||||
inline void setFlags ( unsigned int );
|
inline void setFlags ( unsigned int );
|
||||||
inline void unsetFlags ( unsigned int );
|
inline void unsetFlags ( unsigned int );
|
||||||
void setGCell ( GCell* );
|
void setGCell ( GCell* );
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace Anabatic {
|
||||||
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const;
|
virtual AutoSegment* getPerpandicular ( const AutoSegment* ) const;
|
||||||
virtual void updateGeometry ();
|
virtual void updateGeometry ();
|
||||||
virtual void updateTopology ();
|
virtual void updateTopology ();
|
||||||
|
virtual void forceOnGrid ( Point );
|
||||||
virtual void cacheDetach ( AutoSegment* );
|
virtual void cacheDetach ( AutoSegment* );
|
||||||
virtual void cacheAttach ( AutoSegment* );
|
virtual void cacheAttach ( AutoSegment* );
|
||||||
virtual void updateCache ();
|
virtual void updateCache ();
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include "hurricane/Commons.h"
|
#include "hurricane/Commons.h"
|
||||||
#include "hurricane/DbU.h"
|
#include "hurricane/Box.h"
|
||||||
#include "crlcore/CellGauge.h"
|
#include "crlcore/CellGauge.h"
|
||||||
#include "crlcore/RoutingGauge.h"
|
#include "crlcore/RoutingGauge.h"
|
||||||
#include "anabatic/Constants.h"
|
#include "anabatic/Constants.h"
|
||||||
|
@ -53,6 +53,8 @@ namespace Anabatic {
|
||||||
using Hurricane::Layer;
|
using Hurricane::Layer;
|
||||||
using Hurricane::Technology;
|
using Hurricane::Technology;
|
||||||
using Hurricane::DbU;
|
using Hurricane::DbU;
|
||||||
|
using Hurricane::Point;
|
||||||
|
using Hurricane::Box;
|
||||||
using Hurricane::Net;
|
using Hurricane::Net;
|
||||||
using Hurricane::Contact;
|
using Hurricane::Contact;
|
||||||
using Hurricane::Segment;
|
using Hurricane::Segment;
|
||||||
|
@ -103,6 +105,7 @@ namespace Anabatic {
|
||||||
static inline DbU::Unit getWireWidth ( const Layer* );
|
static inline DbU::Unit getWireWidth ( const Layer* );
|
||||||
static inline DbU::Unit getViaWidth ( const Layer* );
|
static inline DbU::Unit getViaWidth ( const Layer* );
|
||||||
static inline DbU::Unit getExtensionCap ( const Layer* );
|
static inline DbU::Unit getExtensionCap ( const Layer* );
|
||||||
|
static inline Point getNearestGridPoint ( Point, Box constraints );
|
||||||
static inline size_t getSegmentStackSize ();
|
static inline size_t getSegmentStackSize ();
|
||||||
static inline size_t getContactStackSize ();
|
static inline size_t getContactStackSize ();
|
||||||
static inline const vector<AutoSegment*>& getInvalidateds ();
|
static inline const vector<AutoSegment*>& getInvalidateds ();
|
||||||
|
@ -143,6 +146,7 @@ namespace Anabatic {
|
||||||
void _revalidateTopology ();
|
void _revalidateTopology ();
|
||||||
virtual size_t _revalidate ();
|
virtual size_t _revalidate ();
|
||||||
DbU::Unit _getPitch ( size_t depth, unsigned int flags ) const;
|
DbU::Unit _getPitch ( size_t depth, unsigned int flags ) const;
|
||||||
|
Point _getNearestGridPoint ( Point, Box constraints );
|
||||||
Record* _getRecord () const;
|
Record* _getRecord () const;
|
||||||
string _getString () const;
|
string _getString () const;
|
||||||
inline string _getTypeName () const;
|
inline string _getTypeName () const;
|
||||||
|
@ -218,6 +222,7 @@ namespace Anabatic {
|
||||||
inline DbU::Unit Session::getViaWidth ( const Layer* layer ) { return getViaWidth ( getViaDepth(layer) ); }
|
inline DbU::Unit Session::getViaWidth ( const Layer* layer ) { return getViaWidth ( getViaDepth(layer) ); }
|
||||||
inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); }
|
inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); }
|
||||||
inline unsigned int Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); }
|
inline unsigned int Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); }
|
||||||
|
inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); }
|
||||||
|
|
||||||
inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); }
|
inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); }
|
||||||
inline void Session::_doglegReset () { _doglegs.clear(); }
|
inline void Session::_doglegReset () { _doglegs.clear(); }
|
||||||
|
|
Loading…
Reference in New Issue