CNode *CTerm::newaccess (int x, int y, int z, int ident, CNet *net) throw (dup_term, bad_grab, merge_term) { list<CDRGrid::iterator>::iterator itNode; CDRGrid::iterator coord; CNode *pNode; coord = net->_drgrid->origin; coord.set (x, y, z); pNode = &coord.node (); if ((z == 0) && coord.isnodehole()) { pNode = &coord.addnode (); } if (pNode->data.owner) { // Check if the node has already been took by another terminal. if (pNode->data.owner != net) throw bad_grab ( pNode->data.owner->terms[pNode->getid()]->name , net->name , coord.x() , coord.y() , coord.z() , 0 , pNode->data.pri , pNode->terminal() , pNode->data.ident ); // Check if the node belongs to another terminal of this net. // If so, send a merging exception to CNet::newaccess (). if (pNode->getid () != ident) throw merge_term ( pNode->getid() , pNode->data.owner->terms[pNode->getid()]->name , pNode->data.owner->terms[ident]->name , net->name , coord.x() , coord.y() , coord.z() ); return (NULL); } // Check if the node is already in the list (this should never appens !) for (itNode = nodes.begin (); itNode != nodes.end (); itNode++) { if (*itNode == coord) { throw dup_term (name, *itNode); } } pNode->data.owner = net; pNode->data.obstacle = false; pNode->setid (ident); nodes.push_back (coord); return (pNode); }
void CTerm::lockalone (bool global) { CDRGrid::iterator coord; CDRGrid::iterator coord2; int z, i; bool adjust; if (nodes.size() != 1) return; coord = nodes.back (); coord2 = coord; CDRGrid* drgrid = coord._drgrid; if ( (coord.z() > 0) && !global ) return; if ( coord.onAB()) return; //cerr << "+ locking lone terminal : " << coord.node().data.owner->name // << " at " << coord // << endl; // All terminal case, eat up z=1 (ALU2) if not already took. if (coord.z() == 0) { // Go to z=1 (ALU2). //cerr << "+ locking z=1 " << coord << endl; newaccess ( coord.x() , coord.y() , 1 , coord.node().getid() , coord.node().data.owner ); coord2.top(); } if (!global) return; if (coord.z() < 2) { // Go to z=2 (ALU3). //cerr << "+ locking z=2 " << coord2 << endl; newaccess ( coord2.x() , coord2.y() , 2 , coord.node().getid() , coord.node().data.owner ); } if ( drgrid->Z < 3 ) return; // Global terminal : when zupper=4, find the nearest VIA on the // double pitch grid. // Is the terminal in ALU3 (or less). if ( (coord.z() < 3) && (coord.zupper () == 4) ) { if ( coord2.y() % 2 ) { // We are not on the double pitch grid. Try to go there. // Look for up and down grid node. adjust = true; for (i = 0; i < 3; i++) { switch (i) { case 0: coord2.dy (+1); break; case 1: coord2.dy (-2); break; } // Neither node are accessibles, we are probably doomed ... if (i == 2) { coord2.dy (+1); adjust = false; break; } if (coord2.inside()) { if ( !coord2.node().data.obstacle && ( (coord2.node().data.owner == NULL ) || (coord2.node().data.owner == coord.node().data.owner) ) ) { break; } } } if (adjust) { // Adjust to the double grid pitch to z=2 (ALU3). //cerr << "+ locking z=2 (ADJUST) " << coord2 << endl; newaccess ( coord2.x() , coord2.y() , 2 , coord.node().getid() , coord.node().data.owner ); } } } if ( drgrid->Z < 4 ) return; if (coord.z() < 4) { // Go to z=3 (ALU3). //cerr << "+ locking z=3 " << coord2 << endl; newaccess ( coord2.x() , coord2.y() , 3 , coord.node().getid() , coord.node().data.owner ); } }