Improve symmetry management for analog designs.
* Bug: In Hurricane::NetRoutingState::getSymValue(), outrageously bad computation of the symmetric coordinate when the value was superior to the axis... (shame on me). * Change: In Anabatic::Disjkstra::load(), for symmetrically paired nets, check that the axis of symmetry is *outside* the searchArea. Otherwise, the two mirrored areas overlaps and the two nets will unescapably be on top of each other. Issue a warning but still continue. * Change: In Anabatic::Vertex::isRestricted(), allow perpandicular wire to go through struts or thin (less than one routing pitch) node. May have to recheck in the future and restrict to struts only. * Bug: In Bora::HVSlicingNode::updateSymNetAxis(), rescursive call in child node was not systematically done (bad curly brace position). Also checks that symmetries are not empty before accessing the front element (one less core dump).
This commit is contained in:
parent
74e4544a55
commit
7e7e7170ba
|
@ -298,52 +298,68 @@ namespace Anabatic {
|
|||
GCell* c2 = v2->getGCell();
|
||||
|
||||
// Check from GCell 1
|
||||
if ( c1->isNorth(c2) ) {
|
||||
if ( !v1->isNRestricted() ) restricted = false;
|
||||
} else if ( c1->isSouth(c2) ) {
|
||||
if ( !v1->isSRestricted() ) restricted = false;
|
||||
} else if ( c1->isEast (c2) ) {
|
||||
if ( !v1->isERestricted() ) restricted = false;
|
||||
} else if ( c1->isWest (c2) ) {
|
||||
if ( !v1->isWRestricted() ) restricted = false;
|
||||
} else {
|
||||
cerr << Error( "GCells are not side by side." ) << endl;
|
||||
if ( c1->isNorth(c2) and not v1->isNRestricted() ) restricted = false;
|
||||
else if ( c1->isSouth(c2) and not v1->isSRestricted() ) restricted = false;
|
||||
else if ( c1->isEast (c2) and not v1->isERestricted() ) restricted = false;
|
||||
else if ( c1->isWest (c2) and not v1->isWRestricted() ) restricted = false;
|
||||
// else {
|
||||
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
|
||||
// " v1:%s\n"
|
||||
// " v2:%s"
|
||||
// , getString(v1).c_str()
|
||||
// , getString(v2).c_str()
|
||||
// ) << endl;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (restricted) {
|
||||
cdebug_log(112,0) << "v1 -> v2 edge is restricted." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isVertical() and (c1->getWidth() < hpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 1 is too narrow for V edges." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isHorizontal() and (c1->getHeight() < vpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 1 is too narrow for H edges." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( (c1->getWidth() < hpitch)
|
||||
||(c1->getHeight() < vpitch)
|
||||
||(restricted)
|
||||
) return true;
|
||||
else {
|
||||
restricted = true;
|
||||
// Check from GCell 2
|
||||
if ( c2->isNorth(c1) ) {
|
||||
if ( !v2->isNRestricted() ) restricted = false;
|
||||
} else if ( c2->isSouth(c1) ) {
|
||||
if ( !v2->isSRestricted() ) restricted = false;
|
||||
} else if ( c2->isEast (c1) ) {
|
||||
if ( !v2->isERestricted() ) restricted = false;
|
||||
} else if ( c2->isWest (c1) ) {
|
||||
if ( !v2->isWRestricted() ) restricted = false;
|
||||
} else {
|
||||
cerr << Error( "GCells are not side by side." ) << endl;
|
||||
if ( c2->isNorth(c1) and not v2->isNRestricted() ) restricted = false;
|
||||
else if ( c2->isSouth(c1) and not v2->isSRestricted() ) restricted = false;
|
||||
else if ( c2->isEast (c1) and not v2->isERestricted() ) restricted = false;
|
||||
else if ( c2->isWest (c1) and not v2->isWRestricted() ) restricted = false;
|
||||
// else {
|
||||
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
|
||||
// " v1:%s\n"
|
||||
// " v2:%s"
|
||||
// , getString(v1).c_str()
|
||||
// , getString(v2).c_str()
|
||||
// ) << endl;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (restricted) {
|
||||
cdebug_log(112,0) << "v2 -> v1 edge is restricted." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( (c2->getWidth() < hpitch)
|
||||
||(c2->getHeight() < vpitch)
|
||||
||(restricted)
|
||||
) return true;
|
||||
else {
|
||||
if ((v2->getGCell()->isStrut())){
|
||||
if (e->isMaxCapacity(net)) {
|
||||
if ( e->isVertical() and (c2->getWidth() < hpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 2 is too narrow for V edges." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isHorizontal() and (c2->getHeight() < vpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 2 is too narrow for H edges." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( v2->getGCell()->isStrut() and e->isMaxCapacity(net) ) {
|
||||
cdebug_log(112,0) << "Overcapacity:" << e << endl;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1568,6 +1584,34 @@ namespace Anabatic {
|
|||
rp->getBodyHook()->attach( vcontact->getBodyHook() );
|
||||
}
|
||||
|
||||
if (state and state->isSymmetric() and not state->isSelfSym() and state->isSymMaster()) {
|
||||
if (state->isSymVertical()) {
|
||||
if ( (_searchArea.getXMin() < state->getSymAxis())
|
||||
and (_searchArea.getXMax() > state->getSymAxis()) ) {
|
||||
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
|
||||
" Vertical symmetry axis @%s is inside the net area %s."
|
||||
, getString(_net->getName()).c_str()
|
||||
, getString(state->getSymNet()->getName()).c_str()
|
||||
, DbU::getValueString(state->getSymAxis()).c_str()
|
||||
, getString(_searchArea).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->isSymHorizontal()) {
|
||||
if ( (_searchArea.getYMin() < state->getSymAxis())
|
||||
and (_searchArea.getYMax() > state->getSymAxis()) ) {
|
||||
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
|
||||
" Horizontal symmetry axis @%s is inside the net area %s."
|
||||
, getString(_net->getName()).c_str()
|
||||
, getString(state->getSymNet()->getName()).c_str()
|
||||
, DbU::getValueString(state->getSymAxis()).c_str()
|
||||
, getString(_searchArea).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_searchArea.inflate( _searchAreaHalo );
|
||||
cdebug_log(112,0) << "Search halo: " << DbU::getValueString(_searchAreaHalo) << endl;
|
||||
cdebug_log(112,0) << "Search area: " << _searchArea << endl;
|
||||
|
@ -2150,6 +2194,7 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
cdebug_log(112,0) << "| ref: " << segment << endl;
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
|
@ -2168,6 +2213,7 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
cdebug_log(112,0) << "| ref: " << segment << endl;
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
|
@ -2330,51 +2376,66 @@ namespace Anabatic {
|
|||
|
||||
void Dijkstra::_createSelfSymSeg ( Segment* segment )
|
||||
{
|
||||
cdebug_log(112,0) << "void Dijkstra::_createSelfSymSeg ( Segment* segment ): " << _net << ", seg: " << segment << endl;
|
||||
cdebug_log(112,1) << "Dijkstra::_createSelfSymSeg(): " << segment << endl;
|
||||
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
//cdebug_log(112,0) << "state: " << state << endl;
|
||||
if ((state != NULL)&&(segment!=NULL)){
|
||||
if (state and segment) {
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(segment);
|
||||
Vertical* v = dynamic_cast<Vertical *>(segment);
|
||||
Point sp, tp;
|
||||
Point sp;
|
||||
Point tp;
|
||||
DbU::Unit axis;
|
||||
Component* sourceContact = segment->getSource();
|
||||
Component* targetContact = segment->getTarget();
|
||||
|
||||
cdebug_log(112,0) << "source: " << sourceContact << endl;
|
||||
cdebug_log(112,0) << "target: " << targetContact << endl;
|
||||
cdebug_log(112,0) << "sym axis: " << DbU::getValueString(state->getSymAxis()) << endl;
|
||||
|
||||
if (h) {
|
||||
if (state->isSymHorizontal()) {
|
||||
cdebug_log(112,0) << "H case Horizontal" << endl;
|
||||
cdebug_log(112,0) << "Horizontal + Horizontal symmetry." << endl;
|
||||
|
||||
sp = Point( sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
|
||||
tp = Point( targetContact->getX(), state->getSymValue(targetContact->getY()) );
|
||||
axis = state->getSymValue( segment->getY() );
|
||||
} else if (state->isSymVertical()) {
|
||||
cdebug_log(112,0) << "H case Vertical" << endl;
|
||||
cdebug_log(112,0) << "Horizontal + Vertical symmetry." << endl;
|
||||
|
||||
sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() );
|
||||
tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() );
|
||||
axis = segment->getY();
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Horizontal + Unknown symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
//cerr << "sp: " << sp << endl;
|
||||
//cerr << "tp: " << tp << endl;
|
||||
|
||||
cdebug_log(112,0) << "sp: " << sp << endl;
|
||||
cdebug_log(112,0) << "tp: " << tp << endl;
|
||||
|
||||
GCell* sgcell = _anabatic->getGCellUnder( sp );
|
||||
GCell* tgcell = _anabatic->getGCellUnder( tp );
|
||||
//cerr << "Gcell: " << sgcell << endl;
|
||||
//cerr << "Gcell: " << tgcell << endl;
|
||||
|
||||
cdebug_log(112,0) << "GCell: " << sgcell << endl;
|
||||
cdebug_log(112,0) << "GCell: " << tgcell << endl;
|
||||
|
||||
Vertex* svertex = sgcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
Vertex* tvertex = tgcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
|
||||
Contact* sourceSym = NULL;
|
||||
Contact* targetSym = NULL;
|
||||
if (state->isSelfSym()) {
|
||||
cdebug_log(112,0) << "isSelfSym" << endl;
|
||||
cdebug_log(112,0) << "Symmetrical to myself (isSelfSym)." << endl;
|
||||
sourceSym = svertex->getGContact( _net );
|
||||
targetSym = tvertex->getGContact( _net );
|
||||
} else if (state->isSymMaster()){
|
||||
cdebug_log(112,0) << "isSymPair: " << state->getSymNet() << endl;
|
||||
cdebug_log(112,0) << "Symmetrical to (isSymPair): " << state->getSymNet() << endl;
|
||||
sourceSym = svertex->getGContact( state->getSymNet() );
|
||||
targetSym = tvertex->getGContact( state->getSymNet() );
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Unknown Net pairing symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2386,7 +2447,7 @@ namespace Anabatic {
|
|||
, axis
|
||||
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"))
|
||||
);
|
||||
cdebug_log(112,0) << "|| " << segment2 << endl;
|
||||
cdebug_log(112,0) << "| dup:" << segment2 << endl;
|
||||
} else if (v) {
|
||||
if (state->isSymVertical()){
|
||||
//cerr << "V case Vertical" << endl;
|
||||
|
@ -2400,6 +2461,7 @@ namespace Anabatic {
|
|||
axis = segment->getX();
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
GCell* sgcell = _anabatic->getGCellUnder( sp );
|
||||
|
@ -2416,6 +2478,7 @@ namespace Anabatic {
|
|||
targetSym = tvertex->getGContact( state->getSymNet() );
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2430,6 +2493,7 @@ namespace Anabatic {
|
|||
cdebug_log(112,0) << "|| " << segment2 << endl;
|
||||
}
|
||||
}
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -377,10 +377,14 @@ namespace Bora {
|
|||
if (getType() == HorizontalSNode) symmetryType = HSymmetry;
|
||||
if (getType() == VerticalSNode ) symmetryType = VSymmetry;
|
||||
|
||||
|
||||
if (not getChild(childIndex)->isSymmetric(getChild(copyIndex), symmetryType, ShowDiff)) {
|
||||
cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored."
|
||||
, childIndex, copyIndex ) << endl;
|
||||
cerr << Warning( "HVSlicingNode::addSymmetry(int,int)): Children %d and %d are not the same, symmetry is ignored.\n"
|
||||
" child %d: %s\n"
|
||||
" child %d: %s"
|
||||
, childIndex, copyIndex
|
||||
, childIndex, getString(getChild(childIndex)).c_str()
|
||||
, copyIndex , getString(getChild( copyIndex)).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1128,6 +1132,9 @@ namespace Bora {
|
|||
|
||||
void HVSlicingNode::addSymmetryNet ( unsigned int type, Net* net1, Net* net2 )
|
||||
{
|
||||
cerr << "HVSlicingNode::addSymmetryNet(): " << this << endl;
|
||||
cerr << "* " << net1 << endl;
|
||||
|
||||
if (checkSymmetryNet(type,net1,net2)) {
|
||||
cerr << Warning( "HVSlicingNode::addSymmetryNet(): Net symmetry already set." ) << endl;
|
||||
return;
|
||||
|
@ -1201,6 +1208,13 @@ namespace Bora {
|
|||
}
|
||||
|
||||
for ( const NetSymmetry& symNet : _netSymmetries ) {
|
||||
if (_symmetries.empty())
|
||||
throw Error( "HVSlicingNode::updateSymNetAxis(): \n"
|
||||
" Symmetry request for \"%s\" in non-symmetrical node \"%s\"."
|
||||
, getString(get<1>(symNet)->getName()).c_str()
|
||||
, getString(this).c_str()
|
||||
);
|
||||
|
||||
SlicingNode* n1 = getChild( _symmetries.front().first );
|
||||
SlicingNode* n2 = getChild( _symmetries.front().second );
|
||||
DbU::Unit xCenter = (n1->getX() + n2->getX() + n2->getWidth())/2;
|
||||
|
@ -1248,13 +1262,13 @@ namespace Bora {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( SlicingNode* child : _children ) {
|
||||
if ( (child->getType() == HorizontalSNode) or (child->getType() == VerticalSNode) )
|
||||
child->updateSymNetAxis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HVSlicingNode::flattenDigitalNets ()
|
||||
|
|
|
@ -86,6 +86,7 @@ namespace Bora {
|
|||
DbU::Unit addedDistance = 0;
|
||||
|
||||
if (Vertex::isRestricted(vcurr, vnext, e, _hpitch, _vpitch, _net)) {
|
||||
cdebug_log(112,1) << "Unreachable, restricted "<< e << std::endl;
|
||||
distance = Vertex::unreachable;
|
||||
} else {
|
||||
if ( (vcurr->getGCell()->isMatrix()) and (vnext->getGCell()->isMatrix()) ) {
|
||||
|
|
|
@ -30,9 +30,8 @@ namespace Hurricane {
|
|||
|
||||
DbU::Unit NetRoutingState::getSymValue( DbU::Unit v ) const
|
||||
{
|
||||
if (v < _axis) {
|
||||
return _axis + (_axis-v);
|
||||
} else return _axis;
|
||||
if (v < _axis) return _axis + (_axis-v);
|
||||
return 2*_axis - v ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ import Katana
|
|||
import Bora
|
||||
|
||||
|
||||
helpers.setTraceLevel( 100 )
|
||||
#helpers.setTraceLevel( 100 )
|
||||
|
||||
|
||||
NMOS = Transistor.NMOS
|
||||
|
|
|
@ -9,7 +9,7 @@ import helpers
|
|||
import helpers.io
|
||||
from helpers import trace
|
||||
|
||||
helpers.setTraceLevel( 100 )
|
||||
#helpers.setTraceLevel( 100 )
|
||||
|
||||
import Analog
|
||||
from Analog import Device
|
||||
|
|
|
@ -7,8 +7,7 @@ from Hurricane import Box
|
|||
import helpers
|
||||
from helpers import trace
|
||||
|
||||
helpers.staticInitialization( quiet=True )
|
||||
helpers.setTraceLevel( 1000 )
|
||||
#helpers.setTraceLevel( 1000 )
|
||||
|
||||
try:
|
||||
import Analog
|
||||
|
|
|
@ -7,8 +7,7 @@ from Hurricane import Box
|
|||
import helpers
|
||||
from helpers import trace
|
||||
|
||||
helpers.staticInitialization( quiet=True )
|
||||
helpers.setTraceLevel( 1000 )
|
||||
#helpers.setTraceLevel( 1000 )
|
||||
|
||||
try:
|
||||
import Analog
|
||||
|
|
|
@ -8,8 +8,7 @@ import helpers
|
|||
import helpers.io
|
||||
from helpers import trace
|
||||
|
||||
helpers.staticInitialization( quiet=True )
|
||||
helpers.setTraceLevel( 1000 )
|
||||
#helpers.setTraceLevel( 1000 )
|
||||
|
||||
try:
|
||||
import Analog
|
||||
|
|
|
@ -53,6 +53,9 @@ def credits ():
|
|||
|
||||
def runScript ( scriptPath, editor ):
|
||||
try:
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
kw = { }
|
||||
if editor: kw[ 'editor' ] = editor
|
||||
sys.path.insert( 0, os.path.dirname(scriptPath) )
|
||||
|
@ -75,9 +78,9 @@ def runScript ( scriptPath, editor ):
|
|||
#print ' Please check your design hierarchy or the Python syntax.'
|
||||
#print ' Error was:'
|
||||
#print ' %s\n' % e
|
||||
helpers.showPythonTrace( scriptPath, e )
|
||||
helpers.io.catch( e )
|
||||
except Exception, e:
|
||||
helpers.showPythonTrace( scriptPath, e )
|
||||
helpers.io.catch( e )
|
||||
return
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue