* 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).
This commit is contained in:
Jean-Paul Chaput 2002-10-29 18:46:03 +00:00
parent 87fadca82d
commit 39aa243355
10 changed files with 452 additions and 185 deletions

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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. // Check all allocated CNodeAS objects.
void CAStar::CNodeASSet::check (void) void CAStar::CNodeASSet::check (bool cleared)
{ {
int chunk, index, maxindex; 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++) { for (chunk = 0; chunk < _maxchunk; chunk++) {
if (chunk > _maxalloc / D::CHUNK_SIZE) { if (chunk > _maxalloc / D::CHUNK_SIZE) {
@ -104,11 +105,13 @@ void CAStar::CNodeASSet::check (void)
for (index = 0; index < maxindex; index++) { for (index = 0; index < maxindex; index++) {
if ( _chunks[chunk][index].point.inside() ) { if ( _chunks[chunk][index].point.inside() ) {
//cdebug << "+ Not reset CNodeAS found (id := " if (cleared) {
// << _chunks[chunk][index].id cerr << "+ Not reset CNodeAS found (id := "
// << " (point := " << ")" << _chunks[chunk][index].id
// << _chunks[chunk][index].point << " " << (void*)&(_chunks[chunk][index])
// << endl; << " (point := " << _chunks[chunk][index].point << ")"
<< endl;
}
} }
} }
} }
@ -124,41 +127,22 @@ void CAStar::CNodeASSet::check (void)
void CAStar::CNodeASSet::reset (void) void CAStar::CNodeASSet::reset (void)
{ {
int chunk, maxchunk, index, maxindex, maxused_div, maxused_mod; int chunk, index, maxindex, maxused_div, maxused_mod;
//cdebug << "+ CAStar::CNodeAS::resetall()." << endl;
//cdebug << "+ _maxused := " << _maxused << endl;
//cdebug << "+ _maxalloc := " << _maxalloc << endl;
//cdebug << "+ _maxchunk := " << _maxchunk << endl;
if (_maxused > 0) { if (_maxused > 0) {
maxused_div = (_maxused - 1) / D::CHUNK_SIZE; maxused_div = (_maxused - 1) / D::CHUNK_SIZE;
maxused_mod = (_maxused - 1) % D::CHUNK_SIZE; maxused_mod = (_maxused - 1) % D::CHUNK_SIZE;
maxchunk = maxused_div + ( (maxused_mod) ? 1 : 0 ); for (chunk = 0; chunk <= maxused_div; chunk++) {
} else { maxindex = D::CHUNK_SIZE - 1;
maxchunk = 0;
}
for (chunk = 0; chunk < maxchunk; chunk++) { // Incomplete last chunk.
maxindex = D::CHUNK_SIZE - 1; if (chunk == maxused_div) maxindex = maxused_mod;
// Incomplete last chunk. for (index = 0; index <= maxindex; index++) {
if ( (chunk == maxchunk - 1) && (maxused_mod != 0) ) _chunks[chunk][index].reset ();
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 ();
} }
} }
@ -232,9 +216,9 @@ void *CAStar::CNodeAS::operator new (size_t size, CNodeASSet &NS)
// Use a new element. // Use a new element.
NS._maxused++; NS._maxused++;
} while (!new_chunk && } while ( !new_chunk
(NS._maxused <= NS._maxalloc) && && (NS._maxused <= NS._maxalloc)
NS._chunks[chunk][index].intree ); && NS._chunks[chunk][index].intree );
NS._maxalloc = max (NS._maxalloc, NS._maxused); NS._maxalloc = max (NS._maxalloc, NS._maxused);
NS._chunks[chunk][index].id = NS._maxused - 1; NS._chunks[chunk][index].id = NS._maxused - 1;
@ -257,24 +241,12 @@ void CAStar::CNodeAS::reset (void)
queued = false; queued = false;
tagged = false; tagged = false;
//CDRGrid::iterator old_point;
if ( !intree ) { if ( !intree ) {
if ( point.inside() ) { if ( point.inside() ) {
//cdebug << "+ reset CNodeAS (" << this
// << ") id := " << id << ", point " << point
// << " (node := " << &point.node() << ")"
// << endl;
//old_point = point;
point.node().algo = NULL; point.node().algo = NULL;
point.unlink (); 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]) void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success)[6])
{ {
CDRGrid::iterator neighbor; CDRGrid::iterator neighbor;
CDRGrid::iterator neighbor2;
CNet *pNet; CNet *pNet;
CNodeAS *pNodeAS; 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; 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; cost_y = D::cost_ALU3_Y;
} }
for (edge = 0; edge < 6; edge++) (*success)[edge] = NULL;
for (edge = 0; edge < 6; edge++) { 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; neighbor = point;
switch (edge) { switch (edge) {
case 0: cost = cost_x; neighbor.left(); break; 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); pNodeAS = AS (neighbor);
if (!pNodeAS) { if (!pNodeAS) {
//cdebug << "+ new CNodeAS." << endl;
pNodeAS = new (NS) CNodeAS (neighbor); pNodeAS = new (NS) CNodeAS (neighbor);
cdebug << "+ new CNodeAS " << (void*)pNodeAS << "\n";
} }
// Check if the node is an obstacle. // Check if the node is an obstacle.
@ -341,6 +326,39 @@ void CAStar::CNodeAS::successors (CNodeASSet &NS, CNet *net, CNodeAS *(*success
if (neighbor.z()) { if (neighbor.z()) {
// Check if the current net can take the node. // Check if the current net can take the node.
if (!neighbor.take (neighbor.node().data.pri)) continue; 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. // 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. // Tag the node here : prevent double write in queue.
if (!D::optim_AStar_queue) pNodeAS->tagged = true; 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; (*success)[edge] = pNodeAS;
} }
} }
@ -405,6 +425,12 @@ void CAStar::CTree::addterm (CTerm &term)
addnode (pNodeAS); addnode (pNodeAS);
pNodeAS->reset(); pNodeAS->reset();
if (pNodeAS->point.outside ()) {
cerr << "+ TERMINAL NODE OUTSIDE : "
<< (void*)pNodeAS
<< " " << *itNode
<< endl;
}
} }
//cdebug << "+ Done." << endl; //cdebug << "+ Done." << endl;
@ -575,12 +601,18 @@ bool CAStar::step (void) throw (trapped_astar)
for (edge = 0; edge < 6; edge++) { for (edge = 0; edge < 6; edge++) {
if (successors[edge] == NULL) continue; 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. // The successor belongs to the current net.
// (it may be not the actual target). // (it may be not the actual target).
if ( (successors[edge]->point.node().data.owner == net) if ( (successors[edge]->point.node().data.owner == net)
&& (_tree.reached.find (successors[edge]->point.node().getid()) && (_tree.reached.find (successors[edge]->point.node().getid())
== _tree.reached.end())) { == _tree.reached.end())) {
//cerr << " Reached target := \""
// << net->terms[successors[edge]->point.node().getid()]->name
// << " (index := " << successors[edge]->point.node().getid() << ")"
// << endl;
_reached = successors[edge]; _reached = successors[edge];
return (false); return (false);
} }
@ -611,8 +643,6 @@ bool CAStar::nexttarget (void)
// Reset all the nodeAS objects. // Reset all the nodeAS objects.
_NS.reset (); _NS.reset ();
//CNodeAS::checkall ();
//net->_drgrid->nodes->check (); //net->_drgrid->nodes->check ();
// Select the next target. // Select the next target.
@ -622,7 +652,8 @@ bool CAStar::nexttarget (void)
_tree.settarget ( net->terms[i]->lowest() ); _tree.settarget ( net->terms[i]->lowest() );
//cerr << " Next target := \"" //cerr << " Next target := \""
// << net->terms[i]->name // << net->terms[i]->name
// << "\"\n"; // << " (index := " << i << ")"
// << endl;
break; break;
} }
} }
@ -643,8 +674,10 @@ bool CAStar::nexttarget (void)
void CAStar::backtrack (void) void CAStar::backtrack (void)
{ {
CNodeAS *node, *node_prev; CDRGrid::iterator neighbor;
CNet *del_net; CNodeAS *node, *node_prev;
CNet *del_net;
int i;
//cdebug << "+ Backtracking." << endl; //cdebug << "+ Backtracking." << endl;
@ -659,6 +692,23 @@ void CAStar::backtrack (void)
_netsched->queue (del_net); _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); _tree.addnode (node);
node_prev = node; node_prev = node;
@ -694,10 +744,9 @@ bool CAStar::search (void)
for (; step(); ); for (; step(); );
backtrack (); backtrack ();
}
//CNodeAS::checkall (); //check (false);
//net->_drgrid->nodes->check (); }
return (false); return (false);
} }
@ -706,8 +755,7 @@ bool CAStar::search (void)
abort (); abort ();
cmess2 << " > AStar unable to found a path.\n"; cmess2 << " > AStar unable to found a path.\n";
//CNodeAS::checkall (); //check (false);
//net->_drgrid->nodes->check ();
} }
return (true); return (true);
@ -768,13 +816,11 @@ void CAStar::dump (void)
iterations_reroute = 0; iterations_reroute = 0;
iterations_kind = &iterations_route; iterations_kind = &iterations_route;
//if (pNet->name == "acc_i_down") cdebug.on (); //if (pNet->name == "ram_banc1_nadr2x") cdebug.on ();
do { do {
if (hysteresis) { if (hysteresis) {
cdebug << "About to clear." << "\n";
clear (); clear ();
cdebug << "cleared." << "\n";
pri = 255 + (1 << increase++); pri = 255 + (1 << increase++);
@ -785,18 +831,12 @@ void CAStar::dump (void)
else else
pri = 0; pri = 0;
cdebug << "About to load net " << iterations_kind << "\n";
load (pNet, pri, expand); load (pNet, pri, expand);
cdebug << "loading done " << iterations_kind << "\n";
cdebug << "About to route net " << iterations_kind << "\n";
routed = !search (); routed = !search ();
cdebug << "routing done " << iterations_kind << "\n";
*iterations_kind += iterations; *iterations_kind += iterations;
cdebug << "mark 1.\n";
hysteresis = true; hysteresis = true;
cdebug << "mark 2.\n";
} while ((increase < 15) && !routed); } while ((increase < 15) && !routed);
if (increase >= 15) throw reach_max_pri (pNet); if (increase >= 15) throw reach_max_pri (pNet);
@ -805,10 +845,9 @@ void CAStar::dump (void)
clear (); clear ();
//CNodeAS::checkall (); //check (true);
//pNet->_drgrid->nodes->check ();
//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()". // Method : "CMatrixNodes::check()".
void CMatrixNodes::check (void) void CMatrixNodes::check (bool cleared)
{ {
int index; int index;
cdebug << "+ Check routing DB.\n"; cerr << "+ Check Nodes Matrix.\n";
for (index = 0; index < _drgrid->XYZ; index++) { for (index = 0; index < _drgrid->XYZ; index++) {
if ( &(*this)[index] == &hole ) continue; if ( &(*this)[index] == &hole ) continue;
if ( ! (*this)[index].check() ) if (! (*this)[index].check(cleared))
cdebug << " (point := (" << _drgrid->x(index) cerr << "+ Grid point := (" << _drgrid->x(index)
<< "," << _drgrid->y(index) << "," << _drgrid->y(index)
<< "," << _drgrid->z(index) << "))\n"; << "," << _drgrid->z(index) << "))"
<< endl;
} }
} }
@ -840,23 +879,40 @@ void CMatrixNodes::check (void)
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Method : "CNode::check()". // Method : "CNode::check()".
bool CNode::check (void) bool CNode::check (bool cleared)
{ {
CAStar::CNodeAS *nodeAS; CAStar::CNodeAS *nodeAS;
if ( algo != NULL ) { if ( algo != NULL ) {
cdebug << "+ Residual algo structure found!\n"; if (cleared)
cerr << "+ Residual algo structure found !" << endl;
nodeAS = (CAStar::CNodeAS*) algo; nodeAS = (CAStar::CNodeAS*) algo;
if ( nodeAS->point.outside() ) { if ( nodeAS->point.outside() ) {
cdebug << "+ Incoherent algo structure found (node := " cerr << "+ Incoherent algo structure found (node := "
<< this << ") : " << this << ") : "
<< nodeAS << " (id := " << nodeAS->id << ")"; << nodeAS << " (id := " << nodeAS->id << ")"
<< endl;
return ( false ); return ( false );
} }
} }
return ( true ); return ( true );
} }
// -------------------------------------------------------------------
// Method : "CAStar::check()".
void CAStar::check (bool cleared)
{
cerr << "+ Check routing DB.\n";
_drgrid->nodes->check (cleared);
_NS.check (cleared);
}

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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. // Modifiers.
public: void reset (void); public: void reset (void);
public: void check (void); public: void check (bool cleared);
// Friend class (for CNodeAS allocator). // Friend class (for CNodeAS allocator).
friend class CNodeAS; friend class CNodeAS;
@ -285,6 +285,9 @@
public: bool search (void); public: bool search (void);
public: void route (CNet *pNet) throw (reach_max_pri); public: void route (CNet *pNet) throw (reach_max_pri);
// Database integrity check.
public: void check (bool cleared);
}; };

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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()". // 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; int index;
X = x; X = x;
Y = y; Y = y;
Z = z; Z = z;
XY = X * Y; XY = X * Y;
XYZ = XY * Z; XYZ = XY * Z;
size = XY * (Z - 1); size = XY * (Z - 1);
zupper = zup;
if (zupper < 4) throw e_zupper (zupper);
nodes = new CMatrixNodes (this); nodes = new CMatrixNodes (this);

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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: friend ostream &operator<< (ostream &o, iterator &self);
public: void valid (bool validindex) throw (e_matrix_iterator); public: void valid (bool validindex) throw (e_matrix_iterator);
public: int x (void) { return ( _drgrid->x (_index) ); } public: int x (void) { return ( _drgrid->x (_index) ); }
public: int y (void) { return ( _drgrid->y (_index) ); } public: int y (void) { return ( _drgrid->y (_index) ); }
public: int z (void) { return ( _drgrid->z (_index) ); } public: int z (void) { return ( _drgrid->z (_index) ); }
public: bool outside (void) { return ( _index == INT_MAX ); } public: bool outside (void) { return ( _index == INT_MAX ); }
public: bool inside (void) { return ( !outside() ); } public: bool inside (void) { return ( !outside() ); }
public: int manhattan (iterator &other) throw (e_matrix_iterator); 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. // Modifiers.
public: void unlink (void) public: void unlink (void)
@ -253,6 +283,14 @@
public: iterator &up (void) { return ( dy(+1) ); }; public: iterator &up (void) { return ( dy(+1) ); };
public: iterator &bottom (void) { return ( dz(-1) ); }; public: iterator &bottom (void) { return ( dz(-1) ); };
public: iterator &top (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 XY;
public: int XYZ; public: int XYZ;
public: int size; public: int size;
public: int zupper;
public: int cost_x_hor; public: int cost_x_hor;
public: int cost_x_ver; public: int cost_x_ver;
public: int cost_y_hor; public: int cost_y_hor;
@ -277,7 +316,7 @@
public: CMatrixNodes *nodes; public: CMatrixNodes *nodes;
// Constructor. // Constructor.
public: CDRGrid (int x, int y, int z); public: CDRGrid (int x, int y, int z, int zup) throw (e_zupper);
// Destructor. // Destructor.
public: ~CDRGrid (void); public: ~CDRGrid (void);
@ -402,7 +441,7 @@
public: inline int getid (void) { return (data.ident - 1); } public: inline int getid (void) { return (data.ident - 1); }
public: inline bool terminal (void) { return (data.ident != 0); } public: inline bool terminal (void) { return (data.ident != 0); }
public: inline bool locked (void) { return (data.lock); } public: inline bool locked (void) { return (data.lock); }
public: bool check (void); public: bool check (bool cleared);
}; };
@ -419,7 +458,7 @@
// Modifiers. // Modifiers.
public: void obstacle (CRect &rect, int z); 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<char>(drgrid) { } public: CMatrixPri (CDRGrid *drgrid) : TMatrix<char>(drgrid) { }
// Modifiers. // Modifiers.
public: void clear (void); public: void clear (void);
public: void load (CNet &net, bool global, int expand=0); public: void load (CNet &net, bool global, int expand=0);
public: bool take (int pri, int index); public: bool take (int pri, int index);
public: void findfree (int index, CNet &net); public: void findfree (int index, CNet &net);
// Internal methods. // Internal methods.
private: char nextPri (char curpri); private: char nextPri (char curpri);

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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) void CTerm::lockalone (bool global)
{ {
CDRGrid::iterator coord; CDRGrid::iterator coord;
int zCoord, zMax, z; CDRGrid::iterator coord2;
int z, i;
bool adjust;
if (nodes.size() != 1) return; if (nodes.size() != 1) return;
coord = nodes.back (); coord = nodes.back ();
zCoord = coord.z(); coord2 = coord;
zMax = min(coord._drgrid->Z - 1, 3);
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() newaccess ( coord.x()
, coord.y() , 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().getid()
, coord.node().data.owner , coord.node().data.owner
); );

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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); cy = _drgrid->y(index);
coord = _drgrid->origin; 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) { while (!freed) {
radius += 1; 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). // Enable z=1 (in case of global signal, no effet otherwise).
if (coord.z() < _drgrid->Z - 1) (*this)[ coord.dz(1) ] = (char)1; if (coord.z() < _drgrid->Z - 1) (*this)[ coord.dz(1) ] = (char)1;
if (global) { if (global) findfree (coord, net);
// 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);
}
}
continue; continue;
} }
@ -190,29 +191,14 @@ void CMatrixPri::load (CNet &net, bool global, int expand)
(*this)[ coord.dz(1) ] = nextPri (currentPri); (*this)[ coord.dz(1) ] = nextPri (currentPri);
nextBorder->push (new CDRGrid::iterator (coord)); nextBorder->push (new CDRGrid::iterator (coord));
if (global) { if (global) findfree (coord, net);
// 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);
}
}
// Enable z=2 (in case of global signal, no effet otherwise). // Enable z=2 (in case of global signal, no effet otherwise).
(*this)[ coord.dz(1) ] = (char)1; (*this)[ coord.dz(1) ] = (char)1;
// Look if the upper node is blocked, in that case expand the // Look if the upper node is blocked, in that case expand the
// allowed zone till a non-blocked node is found. // allowed zone till a non-blocked node is found.
if (global) { if (global) findfree (coord, net);
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);
}
}
} }
} }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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; drgrid = NULL;
netsched = NULL; netsched = NULL;
loaded = false; loaded = false;
insave = false;
} }
@ -82,7 +83,7 @@ CRBox::CRBox (int rtype, bool debug)
// Creating routing matrix. // Creating routing matrix.
cdebug << " Routing matrix size := (10, 15, 5)\n"; 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". // Adding signal "sig_one".

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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: CDRGrid *drgrid;
public: MNet nets; public: MNet nets;
public: bool loaded; public: bool loaded;
public: bool insave;
public: bool rglobal; public: bool rglobal;
// MBK dedicated Attributes. // MBK dedicated Attributes.
@ -59,8 +60,8 @@
// Modifiers. // Modifiers.
public: CNet *getnet (string &signame); public: CNet *getnet (string &signame);
public: CNet *getnet (char *signame); public: CNet *getnet (char *signame);
public: void mbkload (MBK::CFig *mbkfig, int z, int rtype); public: void mbkload (MBK::CFig *mbkfig, int z, int zup, int rtype);
public: void mbksave (string &name); public: void mbksave (string &name) throw (except_done);
public: void route (void); public: void route (void);
}; };

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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()". // 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::MIns::iterator itIns, endInstances, endOrphans;
MBK::MLosig::iterator endSig; MBK::MLosig::iterator endSig;
@ -105,7 +105,7 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype)
<< mX << "," << mY << "," << mZ << "].\n"; << mX << "," << mY << "," << mZ << "].\n";
// Allocating the routing grid. // 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()); 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. if ( !node->terminal() ) node->data.obstacle = true;
for (zz = 4; zz < mZ; zz += 2) { }
for (x = 2; x < mX; x += 2) { }
for (y = 1; y < mY - 1; y++) { break;
node = &( coord.set(x,y,zz).node() ); case 1:
// Horizontal tracks.
if ( !node->terminal() ) node->data.obstacle = true; 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. // This flag ensure that a figure has been successfully loaded.
loaded = true; loaded = true;
@ -409,14 +409,14 @@ void CRBox::mbkload (MBK::CFig *mbkfig, int z, int rtype)
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Modifier : "CRBox::mbksave()". // 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; bool inseg;
CRect rect; CRect rect;
CDRGrid::iterator coord; CDRGrid::iterator coord;
CNode *node; CNode *node;
CNet *pNextNet, *pNet; CNet *pNextNet, *pNet, *pNetTop, *pNetBot;
MBK::phseg_list seg; MBK::phseg_list seg;
MBK::phvia_list via; MBK::phvia_list via;
MNet::iterator itNet, endNet; MNet::iterator itNet, endNet;
@ -429,6 +429,11 @@ void CRBox::mbksave (string &name)
return; return;
} }
if (insave) throw except_done ();
insave = true;
cmess2 << "\n"; cmess2 << "\n";
cmess1 << " o Dumping routing grid.\n"; cmess1 << " o Dumping routing grid.\n";
@ -578,12 +583,86 @@ void CRBox::mbksave (string &name)
via.DX = 0; via.DX = 0;
via.DY = 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. // Plane loop for VIAs.
for (x = 0; x < mX; x++) { for (x = 0; x < mX; x++) {
for (y = 0; y < mY; y++) { for (y = 0; y < mY; y++) {
// Loop on Z axis. // Loop on Z axis.
for (z = 1; z < mZ; z++) { for (z = 1; z < mZ; z++) {
if ( (z >= drgrid->zupper) && ( (x % 2) || (y % 2) ) )
break;
node = & ( coord.set(x,y,z).node() ); node = & ( coord.set(x,y,z).node() );
if (coord.inside()) pNet = node->data.owner; if (coord.inside()) pNet = node->data.owner;
else pNet = NULL; else pNet = NULL;
@ -602,6 +681,7 @@ void CRBox::mbksave (string &name)
} // End of Z axis loop. } // End of Z axis loop.
} }
} // End of plane loop for VIAs. } // End of plane loop for VIAs.
# endif
// Special case of nets with only one terminal. // Special case of nets with only one terminal.

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- 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. // 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" cout << "\n"
<< " o Usage : \"nero [-h] [-v] [-V] [-c] [-2] [-3] [-4] [-5] [-6]\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. // End of Local Namespace.
@ -156,11 +168,12 @@ int main (int argc, char *argv[])
, "2002" , "2002"
, ALLIANCE_VERSION , ALLIANCE_VERSION
); );
serial ();
cmess1 << "\n"; cmess1 << "\n";
} }
if (options["h"]->parsed) { if (options["h"]->parsed) {
print_help (); help ();
exit (0); exit (0);
} }
@ -169,7 +182,7 @@ int main (int argc, char *argv[])
cerr << " Missing mandatory argument <netlist> or <routed> (or both)\n"; cerr << " Missing mandatory argument <netlist> or <routed> (or both)\n";
cerr << "\n"; cerr << "\n";
print_help (); help ();
throw except_done (); throw except_done ();
} }
@ -204,13 +217,21 @@ int main (int argc, char *argv[])
crbox = new CRBox (); crbox = new CRBox ();
//crbox = new CRBox (global, true); //crbox = new CRBox (global, true);
//cdebug.on (); //cdebug.on ();
crbox->mbkload (fig, layers, global); crbox->mbkload (fig, layers, 4, global);
crbox->route (); crbox->route ();
//cdebug.off (); //cdebug.off ();
crbox->mbksave (name_routed); 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) { catch (bad_grab &e) {
cerr << herr ("\n"); cerr << herr ("\n");
cerr << " Net \"" << e.netName << "\" attempt to grab node (" cerr << " Net \"" << e.netName << "\" attempt to grab node ("