From 39aa24335517959c32cbece9631ab917a694e6a9 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 29 Oct 2002 18:46:03 +0000 Subject: [PATCH] * nero/src/poire.cpp, nero/src/AAstar.cpp, nero/src/ADefs.h, nero/src/MNet.h, nero/src/MPri.h, nero/src/MDRGrid.cpp, nero/src/MDefs.h, nero/src/RBox.cpp, nero/src/RMBK.cpp, nero/src/RDefs.cpp, nero/src/nero.cpp : - Ajout d'un "serial" (affiche) pour que l'utilisateur puisse savoir simplement quant le programme a ete reinstalle (a numero de version invariant). Suggestion Patricia. - Bug : CAStar::CNodeASSet::reset() : lorsqu'exactement 4097 elements CNodeAS etaient utilises, le reset ne reinitialisait pas le 4097 ieme (index := 4096). Ce qui explique les "coredumps" residuels (mort aux modulos !). - Bug : pour les ALU superieurs ou egaux a 5, respecter la distance minimale bab de 8 n'oblige pas seulement a invalider une piste sur deux, mais aussi a controler qu'au sein d'une meme piste deux segments consecutifs respectent cet espacement. On implemente cet effet dans "CAStar::CNodeAS::successors()" et "CAStar::backtrack()". - Modification : ajout d'un membre "zupper" a CDRGrid qui contient l'index "z" a partir duquel on passe en double pitch. Actuellement il n'est pas modifiable depuis la ligne de commande de nero. On rend se membre accessible au travers des iterateurs de CDRGrid : membre "::zupper()" (remarque : il faudra generaliser l'acces aux membres de la matrice au travers de l'iterateur, c'est pratique). - Modification : CTerm::lockalone() : quant "zupper" vaut 4 (ALU5) on ajoute un "dog leg vertical" aux terminaux n'ayant qu'un acces pour que la transition vers le double pitch se passe bien. Symptome : si cette ce deport n'est pas fait, l'Hadamard ne converge pas (boucle du routage global sur "init", "c2i" et ??) - Modification : CRBox::mbksave() : nouvelle facon de sauvegarder les VIAs : au lieu de balayer la matrice puis de faire une boucle verticale pour chercher les VIAs on balaye piste par piste dans la direction prerentielle de routage. Ceci permet d'eviter qu'a l'interface 1pitch / 2pitch on ne mette deux VIAs sur des pitchs successifs (cas des segments superposes d'un meme signal en train de s'ajuster au nouveau pitch). --- alliance/src/nero/src/AAstar.cpp | 228 +++++++++++++++++++----------- alliance/src/nero/src/ADefs.h | 7 +- alliance/src/nero/src/MDRGrid.cpp | 19 +-- alliance/src/nero/src/MDefs.h | 69 +++++++-- alliance/src/nero/src/MNet.cpp | 91 +++++++++++- alliance/src/nero/src/MPri.cpp | 40 ++---- alliance/src/nero/src/RBox.cpp | 5 +- alliance/src/nero/src/RDefs.h | 7 +- alliance/src/nero/src/RMBK.cpp | 136 ++++++++++++++---- alliance/src/nero/src/nero.cpp | 35 ++++- 10 files changed, 452 insertions(+), 185 deletions(-) diff --git a/alliance/src/nero/src/AAstar.cpp b/alliance/src/nero/src/AAstar.cpp index d70819a5..ab5b801c 100644 --- a/alliance/src/nero/src/AAstar.cpp +++ b/alliance/src/nero/src/AAstar.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: AAstar.cpp,v 1.5 2002/10/24 07:51:33 hcl Exp $ +// $Id: AAstar.cpp,v 1.6 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -85,12 +85,13 @@ CAStar::CNodeASSet::~CNodeASSet (void) // // Check all allocated CNodeAS objects. -void CAStar::CNodeASSet::check (void) +void CAStar::CNodeASSet::check (bool cleared) { int chunk, index, maxindex; - //cdebug << "+ Check all CNodeAS (" << _maxalloc << ")\n"; + cerr << "+ Check all CNodeAS ( used := " << _maxused + << ", allocated := " << _maxalloc << endl; for (chunk = 0; chunk < _maxchunk; chunk++) { if (chunk > _maxalloc / D::CHUNK_SIZE) { @@ -104,11 +105,13 @@ void CAStar::CNodeASSet::check (void) for (index = 0; index < maxindex; index++) { if ( _chunks[chunk][index].point.inside() ) { - //cdebug << "+ Not reset CNodeAS found (id := " - // << _chunks[chunk][index].id - // << " (point := " << ")" - // << _chunks[chunk][index].point - // << endl; + if (cleared) { + cerr << "+ Not reset CNodeAS found (id := " + << _chunks[chunk][index].id + << " " << (void*)&(_chunks[chunk][index]) + << " (point := " << _chunks[chunk][index].point << ")" + << endl; + } } } } @@ -124,41 +127,22 @@ void CAStar::CNodeASSet::check (void) void CAStar::CNodeASSet::reset (void) { - int chunk, maxchunk, index, maxindex, maxused_div, maxused_mod; - - - //cdebug << "+ CAStar::CNodeAS::resetall()." << endl; - //cdebug << "+ _maxused := " << _maxused << endl; - //cdebug << "+ _maxalloc := " << _maxalloc << endl; - //cdebug << "+ _maxchunk := " << _maxchunk << endl; + int chunk, index, maxindex, maxused_div, maxused_mod; if (_maxused > 0) { maxused_div = (_maxused - 1) / D::CHUNK_SIZE; maxused_mod = (_maxused - 1) % D::CHUNK_SIZE; - maxchunk = maxused_div + ( (maxused_mod) ? 1 : 0 ); - } else { - maxchunk = 0; - } + for (chunk = 0; chunk <= maxused_div; chunk++) { + maxindex = D::CHUNK_SIZE - 1; - for (chunk = 0; chunk < maxchunk; chunk++) { - maxindex = D::CHUNK_SIZE - 1; + // Incomplete last chunk. + if (chunk == maxused_div) maxindex = maxused_mod; - // Incomplete last chunk. - if ( (chunk == maxchunk - 1) && (maxused_mod != 0) ) - maxindex = maxused_mod; - - //cdebug << "+ Index range := [" << chunk * D::CHUNK_SIZE - // << "," << chunk * D::CHUNK_SIZE + maxindex << "]" - // << " (chunk := " << chunk << ", maxindex := " << maxindex << ")" - // << endl; - - for (index = 0; index <= maxindex; index++) { - //cdebug << "+ index := " << index - // << " (" << &_chunks[chunk][index] << ")" - // << endl; - _chunks[chunk][index].reset (); + for (index = 0; index <= maxindex; index++) { + _chunks[chunk][index].reset (); + } } } @@ -232,9 +216,9 @@ void *CAStar::CNodeAS::operator new (size_t size, CNodeASSet &NS) // Use a new element. NS._maxused++; - } while (!new_chunk && - (NS._maxused <= NS._maxalloc) && - NS._chunks[chunk][index].intree ); + } while ( !new_chunk + && (NS._maxused <= NS._maxalloc) + && NS._chunks[chunk][index].intree ); NS._maxalloc = max (NS._maxalloc, NS._maxused); NS._chunks[chunk][index].id = NS._maxused - 1; @@ -257,24 +241,12 @@ void CAStar::CNodeAS::reset (void) queued = false; tagged = false; - //CDRGrid::iterator old_point; if ( !intree ) { if ( point.inside() ) { - //cdebug << "+ reset CNodeAS (" << this - // << ") id := " << id << ", point " << point - // << " (node := " << &point.node() << ")" - // << endl; - //old_point = point; point.node().algo = NULL; point.unlink (); - - //old_point.node().check (); - //} else { - // cdebug << "+ reset CNodeAS id := " << id << " has point outside!." << endl; } - //} else { - // cdebug << "+ reset CNodeAS id := " << id << " is in tree." << endl; } } @@ -287,11 +259,13 @@ void CAStar::CNodeAS::reset (void) void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success)[6]) { CDRGrid::iterator neighbor; + CDRGrid::iterator neighbor2; CNet *pNet; CNodeAS *pNodeAS; - int cost_x, cost_y, cost_z, cost, edge; + int cost_x, cost_y, cost_z, cost, edge, i, j; long new_distance, new_remains; + bool skip; @@ -311,7 +285,18 @@ void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success cost_y = D::cost_ALU3_Y; } + for (edge = 0; edge < 6; edge++) (*success)[edge] = NULL; + for (edge = 0; edge < 6; edge++) { + cdebug << "+ successors[] : (before edge " << edge << ")\n"; + for (j = 0; j < 6; j++) { + cdebug << "+ " << (void*)(*success)[j]; + if ((*success)[j] != NULL) + cdebug << " " << (*success)[j]->point << "\n"; + else + cdebug << "\n"; + } + neighbor = point; switch (edge) { case 0: cost = cost_x; neighbor.left(); break; @@ -328,8 +313,8 @@ void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success pNodeAS = AS (neighbor); if (!pNodeAS) { - //cdebug << "+ new CNodeAS." << endl; pNodeAS = new (NS) CNodeAS (neighbor); + cdebug << "+ new CNodeAS " << (void*)pNodeAS << "\n"; } // Check if the node is an obstacle. @@ -341,6 +326,39 @@ void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success if (neighbor.z()) { // Check if the current net can take the node. if (!neighbor.take (neighbor.node().data.pri)) continue; + + // For the junction layer, allow up neighbor (i.e. VIAs) + // only on the 2 pitch grid. + if ( ((neighbor.z() == neighbor.zupper() ) && (edge == 5)) + || ((neighbor.z() == neighbor.zupper() - 1) && (edge == 4)) ) { + if (neighbor.zupper() % 2) { + if (neighbor.x() % 2) continue; + } else { + if (neighbor.y() % 2) continue; + } + } + + if (neighbor.z() >= neighbor.zupper ()) { + skip = false; + + for (i = 0; i < 2; i++) { + neighbor2 = neighbor; + + switch (i) { + case 0: neighbor2.pprev (); break; + case 1: neighbor2.pnext (); break; + } + + if (neighbor2.inside()) { + if ( neighbor2.node().data.obstacle + || !neighbor2.take (neighbor2.node().data.pri) ) { + skip = true; break; + } + } + } + + if (skip) continue; + } } // Case of locked nodes : belongs to global nets, never use it. @@ -375,7 +393,9 @@ void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success // Tag the node here : prevent double write in queue. if (!D::optim_AStar_queue) pNodeAS->tagged = true; - //cdebug << "+ Added to successor list." << endl; + cdebug << "+ Added to successor list [" << edge << "]\n"; + cdebug << "+ " << (void*)pNodeAS << " " << neighbor << "\n"; + cdebug << "+ " << (void*)pNodeAS << " " << pNodeAS->point << "\n"; (*success)[edge] = pNodeAS; } } @@ -405,6 +425,12 @@ void CAStar::CTree::addterm (CTerm &term) addnode (pNodeAS); pNodeAS->reset(); + if (pNodeAS->point.outside ()) { + cerr << "+ TERMINAL NODE OUTSIDE : " + << (void*)pNodeAS + << " " << *itNode + << endl; + } } //cdebug << "+ Done." << endl; @@ -575,12 +601,18 @@ bool CAStar::step (void) throw (trapped_astar) for (edge = 0; edge < 6; edge++) { if (successors[edge] == NULL) continue; - cdebug << "+ " << successors[edge]->point << "\n"; + cdebug << "+ " << "[" << edge << "] " + << (void*)successors[edge] << " " + << successors[edge]->point << "\n"; // The successor belongs to the current net. // (it may be not the actual target). if ( (successors[edge]->point.node().data.owner == net) && (_tree.reached.find (successors[edge]->point.node().getid()) == _tree.reached.end())) { + //cerr << " Reached target := \"" + // << net->terms[successors[edge]->point.node().getid()]->name + // << " (index := " << successors[edge]->point.node().getid() << ")" + // << endl; _reached = successors[edge]; return (false); } @@ -611,8 +643,6 @@ bool CAStar::nexttarget (void) // Reset all the nodeAS objects. _NS.reset (); - - //CNodeAS::checkall (); //net->_drgrid->nodes->check (); // Select the next target. @@ -622,7 +652,8 @@ bool CAStar::nexttarget (void) _tree.settarget ( net->terms[i]->lowest() ); //cerr << " Next target := \"" // << net->terms[i]->name - // << "\"\n"; + // << " (index := " << i << ")" + // << endl; break; } } @@ -643,8 +674,10 @@ bool CAStar::nexttarget (void) void CAStar::backtrack (void) { - CNodeAS *node, *node_prev; - CNet *del_net; + CDRGrid::iterator neighbor; + CNodeAS *node, *node_prev; + CNet *del_net; + int i; //cdebug << "+ Backtracking." << endl; @@ -659,6 +692,23 @@ void CAStar::backtrack (void) _netsched->queue (del_net); } + if (node->point.z() >= node->point.zupper()) { + for (i = 0; i < 2; i++) { + neighbor = node->point; + + switch (i) { + case 0: neighbor.pnext(); break; + case 1: neighbor.pprev(); break; + } + + if (neighbor.inside() && (neighbor.node().data.pri > 0)) { + del_net = neighbor.node().data.owner; + del_net->unroute (); + _netsched->queue (del_net); + } + } + } + _tree.addnode (node); node_prev = node; @@ -694,10 +744,9 @@ bool CAStar::search (void) for (; step(); ); backtrack (); - } - //CNodeAS::checkall (); - //net->_drgrid->nodes->check (); + //check (false); + } return (false); } @@ -706,8 +755,7 @@ bool CAStar::search (void) abort (); cmess2 << " > AStar unable to found a path.\n"; - //CNodeAS::checkall (); - //net->_drgrid->nodes->check (); + //check (false); } return (true); @@ -768,13 +816,11 @@ void CAStar::dump (void) iterations_reroute = 0; iterations_kind = &iterations_route; - //if (pNet->name == "acc_i_down") cdebug.on (); + //if (pNet->name == "ram_banc1_nadr2x") cdebug.on (); do { if (hysteresis) { - cdebug << "About to clear." << "\n"; clear (); - cdebug << "cleared." << "\n"; pri = 255 + (1 << increase++); @@ -785,18 +831,12 @@ void CAStar::dump (void) else pri = 0; - cdebug << "About to load net " << iterations_kind << "\n"; load (pNet, pri, expand); - cdebug << "loading done " << iterations_kind << "\n"; - cdebug << "About to route net " << iterations_kind << "\n"; routed = !search (); - cdebug << "routing done " << iterations_kind << "\n"; *iterations_kind += iterations; - cdebug << "mark 1.\n"; hysteresis = true; - cdebug << "mark 2.\n"; } while ((increase < 15) && !routed); if (increase >= 15) throw reach_max_pri (pNet); @@ -805,10 +845,9 @@ void CAStar::dump (void) clear (); - //CNodeAS::checkall (); - //pNet->_drgrid->nodes->check (); + //check (true); - //if (pNet->name == "ctl.seq_ep_30") exit (0); + //if (pNet->name == "cal_q_alu 0") { emergency (); exit (1); } } @@ -817,20 +856,20 @@ void CAStar::dump (void) // ------------------------------------------------------------------- // Method : "CMatrixNodes::check()". -void CMatrixNodes::check (void) +void CMatrixNodes::check (bool cleared) { int index; - cdebug << "+ Check routing DB.\n"; + cerr << "+ Check Nodes Matrix.\n"; for (index = 0; index < _drgrid->XYZ; index++) { if ( &(*this)[index] == &hole ) continue; - if ( ! (*this)[index].check() ) - cdebug << " (point := (" << _drgrid->x(index) + if (! (*this)[index].check(cleared)) + cerr << "+ Grid point := (" << _drgrid->x(index) << "," << _drgrid->y(index) - << "," << _drgrid->z(index) << "))\n"; - + << "," << _drgrid->z(index) << "))" + << endl; } } @@ -840,23 +879,40 @@ void CMatrixNodes::check (void) // ------------------------------------------------------------------- // Method : "CNode::check()". -bool CNode::check (void) +bool CNode::check (bool cleared) { CAStar::CNodeAS *nodeAS; if ( algo != NULL ) { - cdebug << "+ Residual algo structure found!\n"; + if (cleared) + cerr << "+ Residual algo structure found !" << endl; nodeAS = (CAStar::CNodeAS*) algo; if ( nodeAS->point.outside() ) { - cdebug << "+ Incoherent algo structure found (node := " + cerr << "+ Incoherent algo structure found (node := " << this << ") : " - << nodeAS << " (id := " << nodeAS->id << ")"; + << nodeAS << " (id := " << nodeAS->id << ")" + << endl; + return ( false ); } } return ( true ); } + + + + +// ------------------------------------------------------------------- +// Method : "CAStar::check()". + +void CAStar::check (bool cleared) +{ + cerr << "+ Check routing DB.\n"; + + _drgrid->nodes->check (cleared); + _NS.check (cleared); +} diff --git a/alliance/src/nero/src/ADefs.h b/alliance/src/nero/src/ADefs.h index d865d318..0cea111b 100644 --- a/alliance/src/nero/src/ADefs.h +++ b/alliance/src/nero/src/ADefs.h @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: ADefs.h,v 1.2 2002/10/13 14:22:47 jpc Exp $ +// $Id: ADefs.h,v 1.3 2002/10/29 18:46:03 jpc Exp $ // // /-----------------------------------------------------------------\ // | | @@ -177,7 +177,7 @@ // Modifiers. public: void reset (void); - public: void check (void); + public: void check (bool cleared); // Friend class (for CNodeAS allocator). friend class CNodeAS; @@ -285,6 +285,9 @@ public: bool search (void); public: void route (CNet *pNet) throw (reach_max_pri); + + // Database integrity check. + public: void check (bool cleared); }; diff --git a/alliance/src/nero/src/MDRGrid.cpp b/alliance/src/nero/src/MDRGrid.cpp index 79664022..6d60c85f 100644 --- a/alliance/src/nero/src/MDRGrid.cpp +++ b/alliance/src/nero/src/MDRGrid.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: MDRGrid.cpp,v 1.2 2002/10/17 21:57:27 jpc Exp $ +// $Id: MDRGrid.cpp,v 1.3 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -324,17 +324,20 @@ int CDRGrid::iterator::manhattan (iterator &other) // ------------------------------------------------------------------- // Constructor : "CDRGrid::CDRGrid()". -CDRGrid::CDRGrid (int x, int y, int z) + CDRGrid::CDRGrid (int x, int y, int z, int zup) throw (e_zupper) { int index; - X = x; - Y = y; - Z = z; - XY = X * Y; - XYZ = XY * Z; - size = XY * (Z - 1); + X = x; + Y = y; + Z = z; + XY = X * Y; + XYZ = XY * Z; + size = XY * (Z - 1); + zupper = zup; + + if (zupper < 4) throw e_zupper (zupper); nodes = new CMatrixNodes (this); diff --git a/alliance/src/nero/src/MDefs.h b/alliance/src/nero/src/MDefs.h index 54f6ae91..3b03aeb9 100644 --- a/alliance/src/nero/src/MDefs.h +++ b/alliance/src/nero/src/MDefs.h @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: MDefs.h,v 1.3 2002/10/17 21:57:27 jpc Exp $ +// $Id: MDefs.h,v 1.4 2002/10/29 18:46:03 jpc Exp $ // // /-----------------------------------------------------------------\ // | | @@ -142,6 +142,27 @@ }; + // --------------------------------------------------------------- + // Too small zupper exception. + + class e_zupper : public except_done { + + // Attributes. + public: int zupper; + + // Constructor. + public: e_zupper (int zup) { zupper = zup; } + + // Destructor. + public: ~e_zupper (void) throw () { }; + + // Overridables. + public: const char* what () const throw () { + return ((char*)"\"zupper\" must not be lower than 4."); + } + }; + + // --------------------------------------------------------------- @@ -230,13 +251,22 @@ public: friend ostream &operator<< (ostream &o, iterator &self); - public: void valid (bool validindex) throw (e_matrix_iterator); - public: int x (void) { return ( _drgrid->x (_index) ); } - public: int y (void) { return ( _drgrid->y (_index) ); } - public: int z (void) { return ( _drgrid->z (_index) ); } - public: bool outside (void) { return ( _index == INT_MAX ); } - public: bool inside (void) { return ( !outside() ); } - public: int manhattan (iterator &other) throw (e_matrix_iterator); + public: void valid (bool validindex) throw (e_matrix_iterator); + public: int x (void) { return ( _drgrid->x (_index) ); } + public: int y (void) { return ( _drgrid->y (_index) ); } + public: int z (void) { return ( _drgrid->z (_index) ); } + public: bool outside (void) { return ( _index == INT_MAX ); } + public: bool inside (void) { return ( !outside() ); } + public: bool onAB (void) { if ( (x() == 0) + || (x() == _drgrid->X - 1) + || (y() == _drgrid->Y - 1) + || (y() == 0)) + return (true); + + return (false); + }; + public: int manhattan (iterator &other) throw (e_matrix_iterator); + public: int zupper (void) { return ( _drgrid->zupper ); } // Modifiers. public: void unlink (void) @@ -253,6 +283,14 @@ public: iterator &up (void) { return ( dy(+1) ); }; public: iterator &bottom (void) { return ( dz(-1) ); }; public: iterator &top (void) { return ( dz(+1) ); }; + public: iterator &pnext (void) { if (z() % 2) + return ( right() ); + return ( up() ); + }; + public: iterator &pprev (void) { if (z() % 2) + return ( left() ); + return ( down() ); + }; }; @@ -266,6 +304,7 @@ public: int XY; public: int XYZ; public: int size; + public: int zupper; public: int cost_x_hor; public: int cost_x_ver; public: int cost_y_hor; @@ -277,7 +316,7 @@ public: CMatrixNodes *nodes; // Constructor. - public: CDRGrid (int x, int y, int z); + public: CDRGrid (int x, int y, int z, int zup) throw (e_zupper); // Destructor. public: ~CDRGrid (void); @@ -402,7 +441,7 @@ public: inline int getid (void) { return (data.ident - 1); } public: inline bool terminal (void) { return (data.ident != 0); } public: inline bool locked (void) { return (data.lock); } - public: bool check (void); + public: bool check (bool cleared); }; @@ -419,7 +458,7 @@ // Modifiers. public: void obstacle (CRect &rect, int z); - public: void check (void); + public: void check (bool cleared); }; @@ -448,10 +487,10 @@ public: CMatrixPri (CDRGrid *drgrid) : TMatrix(drgrid) { } // Modifiers. - public: void clear (void); - public: void load (CNet &net, bool global, int expand=0); - public: bool take (int pri, int index); - public: void findfree (int index, CNet &net); + public: void clear (void); + public: void load (CNet &net, bool global, int expand=0); + public: bool take (int pri, int index); + public: void findfree (int index, CNet &net); // Internal methods. private: char nextPri (char curpri); diff --git a/alliance/src/nero/src/MNet.cpp b/alliance/src/nero/src/MNet.cpp index 5cef2e8c..d5bcc44d 100644 --- a/alliance/src/nero/src/MNet.cpp +++ b/alliance/src/nero/src/MNet.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: MNet.cpp,v 1.4 2002/10/24 07:51:33 hcl Exp $ +// $Id: MNet.cpp,v 1.5 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -217,21 +217,98 @@ void CTerm::newaccess (CRect &rect, int z, int ident, CNet *net) void CTerm::lockalone (bool global) { CDRGrid::iterator coord; - int zCoord, zMax, z; + CDRGrid::iterator coord2; + int z, i; + bool adjust; if (nodes.size() != 1) return; coord = nodes.back (); - zCoord = coord.z(); - zMax = min(coord._drgrid->Z - 1, 3); + coord2 = coord; - if ( (zCoord > 0) && !global ) return; + if ( (coord.z() > 0) && !global ) return; + if ( coord.onAB()) return; - for (z = (global) ? zMax : 1; z > zCoord; z--) { + //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() - , z + , 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 + ); + } + + + // 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 (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 ); diff --git a/alliance/src/nero/src/MPri.cpp b/alliance/src/nero/src/MPri.cpp index 3b3581bb..9b95e7e5 100644 --- a/alliance/src/nero/src/MPri.cpp +++ b/alliance/src/nero/src/MPri.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: MPri.cpp,v 1.4 2002/10/24 07:51:33 hcl Exp $ +// $Id: MPri.cpp,v 1.5 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -47,6 +47,15 @@ void CMatrixPri::findfree (int index, CNet &net) cy = _drgrid->y(index); coord = _drgrid->origin; + // Check for blocked upper nodes. + other = (*_drgrid->nodes)[index].data.owner; + + if ( ! (*_drgrid->nodes)[index].data.obstacle + && ((other == NULL) || (other == &net)) ) + return; + + cdebug << "Looking for an escape!\n" << "\n"; + while (!freed) { radius += 1; @@ -174,15 +183,7 @@ void CMatrixPri::load (CNet &net, bool global, int expand) // Enable z=1 (in case of global signal, no effet otherwise). if (coord.z() < _drgrid->Z - 1) (*this)[ coord.dz(1) ] = (char)1; - if (global) { - // Check for blocked upper nodes. - other = (*_drgrid->nodes)[coord].data.owner; - if ( (*_drgrid->nodes)[coord].data.obstacle - || ((other != NULL) && (other != &net)) ) { - cdebug << "Looking for an escape!\n" << "\n"; - findfree (coord, net); - } - } + if (global) findfree (coord, net); continue; } @@ -190,29 +191,14 @@ void CMatrixPri::load (CNet &net, bool global, int expand) (*this)[ coord.dz(1) ] = nextPri (currentPri); nextBorder->push (new CDRGrid::iterator (coord)); - if (global) { - // Check for blocked upper nodes. - other = (*_drgrid->nodes)[coord].data.owner; - if ( (*_drgrid->nodes)[coord].data.obstacle - || ((other != NULL) && (other != &net)) ) { - cdebug << "Looking for an escape!\n" << "\n"; - findfree (coord, net); - } - } + if (global) findfree (coord, net); // Enable z=2 (in case of global signal, no effet otherwise). (*this)[ coord.dz(1) ] = (char)1; // Look if the upper node is blocked, in that case expand the // allowed zone till a non-blocked node is found. - if (global) { - other = (*_drgrid->nodes)[coord].data.owner; - if ( (*_drgrid->nodes)[coord].data.obstacle - || ((other != NULL) && (other != &net)) ) { - cdebug << "Looking for an escape!\n" << "\n"; - findfree (coord, net); - } - } + if (global) findfree (coord, net); } } diff --git a/alliance/src/nero/src/RBox.cpp b/alliance/src/nero/src/RBox.cpp index e439b949..5819b890 100644 --- a/alliance/src/nero/src/RBox.cpp +++ b/alliance/src/nero/src/RBox.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: RBox.cpp,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// $Id: RBox.cpp,v 1.2 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -57,6 +57,7 @@ CRBox::CRBox (void) drgrid = NULL; netsched = NULL; loaded = false; + insave = false; } @@ -82,7 +83,7 @@ CRBox::CRBox (int rtype, bool debug) // Creating routing matrix. cdebug << " Routing matrix size := (10, 15, 5)\n"; - drgrid = new CDRGrid (X, Y, Z); + drgrid = new CDRGrid (X, Y, Z, 4); // Adding signal "sig_one". diff --git a/alliance/src/nero/src/RDefs.h b/alliance/src/nero/src/RDefs.h index c7590dc4..7d9acf0a 100644 --- a/alliance/src/nero/src/RDefs.h +++ b/alliance/src/nero/src/RDefs.h @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: RDefs.h,v 1.1 2002/10/02 21:23:48 jpc Exp $ +// $Id: RDefs.h,v 1.2 2002/10/29 18:46:03 jpc Exp $ // // /-----------------------------------------------------------------\ // | | @@ -43,6 +43,7 @@ public: CDRGrid *drgrid; public: MNet nets; public: bool loaded; + public: bool insave; public: bool rglobal; // MBK dedicated Attributes. @@ -59,8 +60,8 @@ // Modifiers. public: CNet *getnet (string &signame); public: CNet *getnet (char *signame); - public: void mbkload (MBK::CFig *mbkfig, int z, int rtype); - public: void mbksave (string &name); + public: void mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype); + public: void mbksave (string &name) throw (except_done); public: void route (void); }; diff --git a/alliance/src/nero/src/RMBK.cpp b/alliance/src/nero/src/RMBK.cpp index da283a79..cd453132 100644 --- a/alliance/src/nero/src/RMBK.cpp +++ b/alliance/src/nero/src/RMBK.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: RMBK.cpp,v 1.4 2002/10/17 21:57:27 jpc Exp $ +// $Id: RMBK.cpp,v 1.5 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -33,7 +33,7 @@ // ------------------------------------------------------------------- // Modifier : "CRBox::mbkload()". -void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype) +void CRBox::mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype) { MBK::MIns::iterator itIns, endInstances, endOrphans; MBK::MLosig::iterator endSig; @@ -105,7 +105,7 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype) << mX << "," << mY << "," << mZ << "].\n"; // Allocating the routing grid. - drgrid = new CDRGrid (mX, mY, mZ); + drgrid = new CDRGrid (mX, mY, mZ, zup); rect = new MBK::CXRect (fig->XAB1(), fig->YAB1()); @@ -371,31 +371,31 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype) } } - // On routing level above ALU4, use only half of the tracks. + // On routing level above zupper (ALU4), use only half of the tracks. + for (zz = zup; zz < mZ; zz++) { + switch (zz % 2) { + case 0: + // Vertical tracks. + for (x = 2; x < mX; x += 2) { + for (y = 1; y < mY - 1; y++) { + node = &( coord.set(x,y,zz).node() ); - // Vertical tracks. - for (zz = 4; zz < mZ; zz += 2) { - for (x = 2; x < mX; x += 2) { - for (y = 1; y < mY - 1; y++) { - node = &( coord.set(x,y,zz).node() ); - - if ( !node->terminal() ) node->data.obstacle = true; - } + if ( !node->terminal() ) node->data.obstacle = true; + } + } + break; + case 1: + // Horizontal tracks. + for (y = 2; y < mY; y += 2) { + for (x = 1; x < mX; x++) { + node = &( coord.set(x,y,zz).node() ); + if ( !node->terminal() ) node->data.obstacle = true; + } + } + break; } } - // Horizontal tracks. - for (zz = 5; zz < mZ; zz += 2) { - for (y = 2; y < mY; y += 2) { - for (x = 1; x < mX; x++) { - node = &( coord.set(x,y,zz).node() ); - - if ( !node->terminal() ) node->data.obstacle = true; - } - } - } - - // This flag ensure that a figure has been successfully loaded. loaded = true; @@ -409,14 +409,14 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype) // ------------------------------------------------------------------- // Modifier : "CRBox::mbksave()". -void CRBox::mbksave (string &name) + void CRBox::mbksave (string &name) throw (except_done) { - int x, y, z, mX, mY, mZ; + int x, y, z, mX, mY, mZ, pitch, spaceVIA; bool inseg; CRect rect; CDRGrid::iterator coord; CNode *node; - CNet *pNextNet, *pNet; + CNet *pNextNet, *pNet, *pNetTop, *pNetBot; MBK::phseg_list seg; MBK::phvia_list via; MNet::iterator itNet, endNet; @@ -429,6 +429,11 @@ void CRBox::mbksave (string &name) return; } + + if (insave) throw except_done (); + + insave = true; + cmess2 << "\n"; cmess1 << " o Dumping routing grid.\n"; @@ -578,12 +583,86 @@ void CRBox::mbksave (string &name) via.DX = 0; via.DY = 0; + // Plane loop for VIAs. + for (z = 1; z < mZ; z++) { + // Track loop for VIAs. + if (z >= drgrid->zupper) pitch = 2; + else pitch = 1; + + if (z % 2) { + // z=1 (ALU2) : horizontal tracks. + for (y = 1; y < mY; y += pitch) { + for (x = 0, spaceVIA = 2; x < mX; x++, spaceVIA++) { + // Bottom node. + pNetBot = NULL; + node = & ( coord.set(x,y,z-1).node() ); + if ( !coord.isnodehole() && coord.inside() ) + pNetBot = node->data.owner; + + // Top node. + pNetTop = NULL; + node = & ( coord.set(x,y,z).node() ); + if ( !coord.isnodehole() && coord.inside() ) + pNetTop = node->data.owner; + + // Are the top & bottom nodes belonging to the same net ? + if ( (pNetBot != NULL) && (pNetBot == pNetTop) ) { + if (spaceVIA < pitch) continue; + + via.TYPE = MBK::env.z2via (z); + via.XVIA = fig->XAB1() + x * D::X_GRID; + via.YVIA = fig->YAB1() + y * D::Y_GRID; + via.NAME = MBK::namealloc(pNetTop->name.c_str ()); + + fig->addphvia (via); + + spaceVIA = 0; + } + } + } + } else { + // z=2 (ALU3) : vertical tracks. + for (x = 1; x < mX; x += pitch) { + for (y = 0, spaceVIA = 2; y < mY; y++, spaceVIA++) { + // Bottom node. + pNetBot = NULL; + node = & ( coord.set(x,y,z-1).node() ); + if ( !coord.isnodehole() && coord.inside() ) + pNetBot = node->data.owner; + + // Top node. + pNetTop = NULL; + node = & ( coord.set(x,y,z).node() ); + if ( !coord.isnodehole() && coord.inside() ) + pNetTop = node->data.owner; + + // Are the top & bottom nodes belonging to the same net ? + if ( (pNetBot != NULL) && (pNetBot == pNetTop) ) { + if (spaceVIA < pitch) continue; + + via.TYPE = MBK::env.z2via (z); + via.XVIA = fig->XAB1() + x * D::X_GRID; + via.YVIA = fig->YAB1() + y * D::Y_GRID; + via.NAME = MBK::namealloc(pNetTop->name.c_str ()); + + fig->addphvia (via); + + spaceVIA = 0; + } + } + } + } + } + +# if 0 // Plane loop for VIAs. for (x = 0; x < mX; x++) { for (y = 0; y < mY; y++) { - // Loop on Z axis. for (z = 1; z < mZ; z++) { + if ( (z >= drgrid->zupper) && ( (x % 2) || (y % 2) ) ) + break; + node = & ( coord.set(x,y,z).node() ); if (coord.inside()) pNet = node->data.owner; else pNet = NULL; @@ -602,6 +681,7 @@ void CRBox::mbksave (string &name) } // End of Z axis loop. } } // End of plane loop for VIAs. +# endif // Special case of nets with only one terminal. diff --git a/alliance/src/nero/src/nero.cpp b/alliance/src/nero/src/nero.cpp index f5303f2b..aaac0845 100644 --- a/alliance/src/nero/src/nero.cpp +++ b/alliance/src/nero/src/nero.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // -// $Id: nero.cpp,v 1.2 2002/10/13 14:22:47 jpc Exp $ +// $Id: nero.cpp,v 1.3 2002/10/29 18:46:03 jpc Exp $ // // /----------------------------------------------------------------\ // | | @@ -40,7 +40,8 @@ namespace { // --------------------------------------------------------------- // Local functions. - static void print_help (void); + static void help (void); + static void serial (void); @@ -51,9 +52,9 @@ namespace { // ------------------------------------------------------------------- -// Function : "print_help()". +// Function : "help()". -static void print_help (void) +static void help (void) { cout << "\n" << " o Usage : \"nero [-h] [-v] [-V] [-c] [-2] [-3] [-4] [-5] [-6]\n" @@ -86,6 +87,17 @@ static void print_help (void) } + + +// ------------------------------------------------------------------- +// Function : "serial()". + +static void serial (void) +{ + cout << " S/N 20021028.1\n"; +} + + // --------------------------------------------------------------- // End of Local Namespace. @@ -156,11 +168,12 @@ int main (int argc, char *argv[]) , "2002" , ALLIANCE_VERSION ); + serial (); cmess1 << "\n"; } if (options["h"]->parsed) { - print_help (); + help (); exit (0); } @@ -169,7 +182,7 @@ int main (int argc, char *argv[]) cerr << " Missing mandatory argument or (or both)\n"; cerr << "\n"; - print_help (); + help (); throw except_done (); } @@ -204,13 +217,21 @@ int main (int argc, char *argv[]) crbox = new CRBox (); //crbox = new CRBox (global, true); //cdebug.on (); - crbox->mbkload (fig, layers, global); + crbox->mbkload (fig, layers, 4, global); crbox->route (); //cdebug.off (); crbox->mbksave (name_routed); } + catch (e_zupper &e) { + cerr << "\n\n" + << " First \"double pitch\" layer must be at least equal to ALU5 " + << "(here : " << MBK::env.z2alu (e.zupper) << ").\n\n" + << endl; + + exit (1); + } catch (bad_grab &e) { cerr << herr ("\n"); cerr << " Net \"" << e.netName << "\" attempt to grab node ("