1 
2 // -*- C++ -*-
3 
4 # include  <iomanip>
5 # include  <fstream>
6 # include  <sstream>
7 # include  <exception>
8 # include  <iterator>
9 # include  <utility>
10 # include  <string>
11 # include  <vector>
12 # include  <queue>
13 # include  <list>
14 # include  <map>
15 # include  <set>
16 # include  <stdexcept>
17 # include  <cstdlib>
18 # include  <cmath>
19 
20 # include  <unistd.h>
21 
22 
23 
24 
25 
26   // ---------------------------------------------------------------
27   // Use of a cleared priority map exception.
28 
29   class primap_clear : public exception {
30 
31     // Overridables.
what() const32     public: virtual const char* what () const {
33               return ((char*)"Use of cleared signal priority map.");
34             }
35   };
36 
37 
38 
39 
40   // ---------------------------------------------------------------
41   // Coordinate class.
42 
43   class CCoord {
44 
45     public: int  x;
46     public: int  y;
47     public: int  z;
48 
49     // Constructors.
CCoord(void)50     public: CCoord (void)                { x = y = z = 0; }
CCoord(int i,int j,int k)51     public: CCoord (int i, int j, int k) { x = i; y = j; z = k; }
52 
53   };
54 
55 
56 
57 
58   // ---------------------------------------------------------------
59   // Rectangle class.
60 
61   struct CRect {
62 
63     // Attributes.
64     long x1;
65     long y1;
66     long x2;
67     long y2;
68 
69     // Friend.
70     friend ostream &operator<< (ostream &, const CRect *);
71 
72   };
73 
74 
75   class CNode;
76   class CNet;
77 
78 
79   class CNodeData {
80 
81     // Attributes.
82     public: int    pri;
83     public: CNet  *owner;
84     public: CNode *rtree;
85     public: int    ident;
86     public: bool   obstacle;
87     public: bool   lock;
88 
89   };
90 
91 
92   class CNode {
93 
94       public: CNodeData data;
95 
96   };
97 
98 
99 
100 
101   // ---------------------------------------------------------------
102   // Bounding Box class.
103 
104   class CBB {
105 
106     // Attributes.
107     public: int  x1;
108     public: int  y1;
109     public: int  x2;
110     public: int  y2;
111     public: int  hp;
112 
113     // Constructor.
114     public: CBB (void);
115 
116     // Modifiers.
117     public: void merge (CCoord &coord);
118 
119     // Friends.
120     public: friend ostream &operator<< (ostream &o, CBB &self);
121   };
122 
123 
124 
125 
126   // ---------------------------------------------------------------
127   // Matrix iterator exception class.
128 
129   class e_matrix_iterator : public exception {
130 
131     // Attributes.
132     string  message;
133 
134     // Constructor.
e_matrix_iterator(string msg)135     public: e_matrix_iterator (string msg) { message = msg; }
136 
137     // Overridables.
what() const138     public: virtual const char* what () const { return (message.c_str()); }
139 
140   };
141 
142 
143 
144 
145   class CDRGrid;
146 
147 
148 
149 
150   // ---------------------------------------------------------------
151   // Detailed Routing Matrix Class.
152 
153   template<class __CNode__> class TMatrix {
154 
155     // Matrix hollow level class ---------------------------------
156 
157     public: struct _CHollow {
158 
159       typedef map<int, __CNode__*>  _CRow;
160       typedef map<int, _CRow>       _CLayer;
161 
162       // Attributes.
163       public: _CLayer  nodes;
164 
165       // Destructor.
166       ~_CHollow (void);
167 
168       // Modifier.
169       public: __CNode__ &add (int x, int y);
170 
171       // Accessor.
172       public: __CNode__ *get (int x, int y);
173 
174     };
175 
176 
177     // Internal attributes.
178     public: CDRGrid   *_drgrid;
179     public: _CHollow  *_zero;
180     public: __CNode__ *_grid;
181     public: __CNode__   hole;
182 
183 
184     // Constructor.
185     public: TMatrix  (CDRGrid *drgrid);
186     private: TMatrix ( const TMatrix& );
187 
188     // Destructor.
189     public: ~TMatrix (void);
190 
191     // Accessors.
192     public: __CNode__ &operator[] (int index);
193 
194     // Modifiers.
195     public: __CNode__ &add (int index);
196 
197   };
198 
199 
200   typedef  TMatrix<CNode>  CMatrixNodes;
201 
202 
203   class CMatrixPri : public TMatrix<char> {
204 
205     // Internal attributes.
206     protected: CBB   _bb;
207 
208     // Attributes.
209     public: int   offset;
210     public: int   delta;
211     public: bool  cleared;
212 
213 
214     // Constructor.
CMatrixPri(CDRGrid * drgrid)215     public: CMatrixPri (CDRGrid *drgrid)
216               : TMatrix<char>(drgrid)
217               , offset(0)
218               , delta(0)
219               , cleared(false)
220             { }
221 
222     // Modifiers.
223     public: void clear    (void);
224     public: void load     (CNet &net, bool global, int expand=0);
225     public: bool cmp      (int pri, int index);
226     public: void findfree (int index);
227 
228     // Internal methods.
229     private: char  nextPri (char curpri);
230 
231     // Friends.
232     public: friend ostream &operator<< (ostream &o, CMatrixPri &self);
233 
234   };
235 
236 
237 
238 
239   // ---------------------------------------------------------------
240   // Detailed Routing Grid Class.
241 
242   class CDRGrid {
243 
244     // Matrix common iterator class ------------------------------
245 
246     public: class iterator {
247 
248       // Attributes.
249       public: int       _index;
250       public: CDRGrid  *_drgrid;
251 
252       // Constructors.
253       public: iterator (void);
254       public: iterator (iterator &other);
255 
256       // Accessors.
operator int(void)257       public:            operator   int (void) { return ( _index ); }
operator CCoord(void)258       public:            operator   CCoord (void)
259                                     { return ( CCoord (x(), y(), z()) ); }
operator ==(iterator & other)260       public: bool       operator== (iterator &other)
261                                     { return (    (_drgrid == other._drgrid)
262                                                && (_index  == other._index ) ); }
263       public: char      &pri        (void);
264       public: CNode     &node       (void);
265       public: CNode     &addnode    (void);
266 
267       public: friend ostream &operator<< (ostream &o, iterator &self);
268 
269       public: void   valid   (bool validindex) throw (e_matrix_iterator);
x(void)270       public: int    x       (void) { return ( _drgrid->x (_index) ); }
y(void)271       public: int    y       (void) { return ( _drgrid->y (_index) ); }
z(void)272       public: int    z       (void) { return ( _drgrid->z (_index) ); }
outside(void)273       public: bool   outside (void) { return ( _index == INT_MAX ); }
inside(void)274       public: bool   inside  (void) { return ( !outside() ); }
275       public: int    manhattan (iterator &other) throw (e_matrix_iterator);
276 
277       // Modifiers.
278       public: iterator &set    (int x, int y, int z);
set(CCoord & coord)279       public: iterator &set    (CCoord &coord)
280                                  { return ( set(coord.x, coord.y, coord.z) ); }
281       public: iterator &dx     (int d);
282       public: iterator &dy     (int d);
283       public: iterator &dz     (int d);
left(void)284       public: iterator &left   (void) { return ( dx(-1) ); };
right(void)285       public: iterator &right  (void) { return ( dx(+1) ); };
down(void)286       public: iterator &down   (void) { return ( dy(-1) ); };
up(void)287       public: iterator &up     (void) { return ( dy(+1) ); };
bottom(void)288       public: iterator &bottom (void) { return ( dz(-1) ); };
top(void)289       public: iterator &top    (void) { return ( dz(+1) ); };
290 
291     };
292 
293 
294     // Matrix class ----------------------------------------------
295 
296     // Attributes.
297     public: int X;
298     public: int Y;
299     public: int Z;
300     public: int XY;
301     public: int XYZ;
302     public: int size;
303     public: int cost_x_hor;
304     public: int cost_x_ver;
305     public: int cost_y_hor;
306     public: int cost_y_ver;
307     public: int cost_z;
308 
309     public: iterator      origin;
310     public: CMatrixPri   *pri;
311     public: CMatrixNodes *nodes;
312 
313     // Constructor.
314     public: CDRGrid  (int x, int y, int z);
315     private: CDRGrid ( const CDRGrid& );
316 
317     // Destructor.
318     public: ~CDRGrid (void);
319 
320     // Modifiers.
321     public: void  costs (int x_hor, int x_ver, int y_hor, int y_ver, int z);
322 
323     // Utilities.
x(int index)324     public: int x  (int index) { return ( index       % X); }
y(int index)325     public: int y  (int index) { return ((index / X ) % Y); }
z(int index)326     public: int z  (int index) { return ((index / XY) % Z); }
327     public: int dx (int index, int d);
328     public: int dy (int index, int d);
329     public: int dz (int index, int d);
id(int x,int y,int z)330     public: int id (int x, int y, int z)
331                                { return ( x + (X * (y + (Y * z))) ); }
332 
333   };
334 
335 
336 
337 
338 // -------------------------------------------------------------------
339 // Constructor  :  "CDRGrid::iterator::iterator ()".
340 
iterator(void)341 CDRGrid::iterator::iterator (void)
342 {
343   _drgrid = NULL;
344   _index  = INT_MAX;
345 }
346 
347 
348 
349 
350 // -------------------------------------------------------------------
351 // Constructor  :  "CDRGrid::iterator::iterator ()".
352 
iterator(CDRGrid::iterator & other)353 CDRGrid::iterator::iterator (CDRGrid::iterator &other)
354 {
355   _drgrid = other._drgrid;
356   _index  = other._index;
357 }
358 
359 
360 
361 
362 // -------------------------------------------------------------------
363 // Method  :  "CDRGrid::iterator::valid ()".
364 
valid(bool validindex)365 void  CDRGrid::iterator::valid (bool validindex)
366   throw (e_matrix_iterator)
367 {
368   if (_drgrid == NULL) {
369     throw e_matrix_iterator ("Attempt to use an unitialized grid iterator.");
370   }
371 
372   if ( (validindex) && (_index == INT_MAX) )
373     throw e_matrix_iterator ("Attempt to use iterator outside the matrix.");
374 }
375 
376 
377 
378 
379 // -------------------------------------------------------------------
380 // Method  :  "CDRGrid::iterator::set ()".
381 
set(int x,int y,int z)382 CDRGrid::iterator &CDRGrid::iterator::set (int x, int y, int z)
383 {
384   valid (false);
385 
386   _index = _drgrid->dx (_index, x);
387   _index = _drgrid->dy (_index, y);
388   _index = _drgrid->dz (_index, z);
389 
390   return ( *this );
391 }
392 
393 
394 
395 
396 // -------------------------------------------------------------------
397 // Method  :  "CDRGrid::iterator::dx ()".
398 
dx(int d)399 CDRGrid::iterator &CDRGrid::iterator::dx (int d)
400 {
401   valid (false);
402 
403   _index = _drgrid->dx (_index, d);
404 
405   return ( *this );
406 }
407 
408 
409 
410 
411 // -------------------------------------------------------------------
412 // Method  :  "CDRGrid::iterator::dy ()".
413 
dy(int d)414 CDRGrid::iterator &CDRGrid::iterator::dy (int d)
415 {
416   valid (false);
417 
418   _index = _drgrid->dy (_index, d);
419 
420   return ( *this );
421 }
422 
423 
424 
425 
426 // -------------------------------------------------------------------
427 // Method  :  "CDRGrid::iterator::dz ()".
428 
dz(int d)429 CDRGrid::iterator &CDRGrid::iterator::dz (int d)
430 {
431   valid (false);
432 
433   _index = _drgrid->dz (_index, d);
434 
435   return ( *this );
436 }
437 
438 
439 
440 
441 // -------------------------------------------------------------------
442 // Accessor  :  "CDRGrid::iterator::pri".
443 
pri(void)444 char &CDRGrid::iterator::pri (void)
445 {
446   valid (false);
447 
448   return ( (*(_drgrid->pri))[*this] );
449 }
450 
451 
452 
453 
454 // -------------------------------------------------------------------
455 // Accessor  :  "CDRGrid::iterator::node".
456 
node(void)457 CNode &CDRGrid::iterator::node (void)
458 {
459   valid (false);
460 
461   return ( (*(_drgrid->nodes))[*this] );
462 }
463 
464 
465 
466 
467 // -------------------------------------------------------------------
468 // Modifier  :  "CDRGrid::iterator::addnode".
469 
addnode(void)470 CNode &CDRGrid::iterator::addnode (void)
471 {
472   valid (true);
473 
474   return ( _drgrid->nodes->add (this->_index) );
475 }
476 
477 
478 
479 
480 // -------------------------------------------------------------------
481 // Friend : "CDRGrid::iterator::operator<< ()".
482 
operator <<(ostream & o,CDRGrid::iterator & self)483 ostream &operator<< (ostream &o, CDRGrid::iterator &self)
484 {
485   o << "CDRGrid<>::iterator (_drgrid := " << self._drgrid
486     << ", _index := " << self._index
487     << " (" << self.x() << "," << self.y() << "," << self.z() << "))";
488 
489   return ( o );
490 }
491 
492 
493 
494 
495 // -------------------------------------------------------------------
496 // Method : "CDRGrid::iterator::manhattan ()".
497 
manhattan(iterator & other)498 int  CDRGrid::iterator::manhattan (iterator &other)
499   throw (e_matrix_iterator)
500 {
501   long  manhattan;
502 
503 
504   valid (true);
505   other.valid (true);
506 
507   if (_drgrid != other._drgrid)
508     throw (e_matrix_iterator ("Attempt to use iterators from different grids."));
509 
510   manhattan  = abs (x() - other.x()) * _drgrid->cost_x_hor;
511   manhattan += abs (y() - other.y()) * _drgrid->cost_y_ver;
512   manhattan += abs (z() - other.z()) * _drgrid->cost_z;
513 
514   // As we never use ALU1 layer, add the cost of VIA.
515   if (z() == 0)       manhattan += _drgrid->cost_z;
516   if (other.z() == 0) manhattan += _drgrid->cost_z;
517 
518   return (manhattan);
519 }
520 
521 
522 
523 
524 // -------------------------------------------------------------------
525 // Constructor  :  "CDRGrid::CDRGrid()".
526 
CDRGrid(int x,int y,int z)527 CDRGrid::CDRGrid (int x, int y, int z)
528 {
529   X    = x;
530   Y    = y;
531   Z    = z;
532   XY   = X  * Y;
533   XYZ  = XY * Z;
534   size = XY * (Z - 1);
535 
536   nodes = new CMatrixNodes (this);
537   pri   = new CMatrixPri   (this);
538 
539   cost_x_hor = cost_y_ver = cost_z = 1;
540   cost_x_ver = cost_y_hor =          2;
541 
542   // Reference iterator initialisation.
543   origin._drgrid = this;
544   origin._index  = XY;
545 }
546 
547 
548 
549 
550 // -------------------------------------------------------------------
551 // Destructor  :  "CDRGrid::~CDRGrid()".
552 
~CDRGrid(void)553 CDRGrid::~CDRGrid (void)
554 {
555   delete [] nodes;
556   delete [] pri;
557 }
558 
559 
560 
561 
562 // -------------------------------------------------------------------
563 // Modifier  :  "CDRGrid::costs ()".
564 
costs(int x_hor,int x_ver,int y_hor,int y_ver,int z)565 void  CDRGrid::costs (int x_hor, int x_ver, int y_hor, int y_ver, int z)
566 {
567   cost_x_hor = x_hor;
568   cost_x_ver = x_ver;
569   cost_y_hor = y_hor;
570   cost_y_ver = y_ver;
571   cost_z     = z;
572 }
573 
574 
575 
576 
577 // -------------------------------------------------------------------
578 // Modifier  :  "CDRGrid::dx ()".
579 
dx(int index,int d)580 int  CDRGrid::dx (int index, int d)
581 {
582   if ( (index == INT_MAX) || (x(index) + d < 0) || (x(index) + d >= X) )
583     return (INT_MAX);
584 
585   return (index + d);
586 }
587 
588 
589 
590 
591 // -------------------------------------------------------------------
592 // Modifier  :  "CDRGrid::dy ()".
593 
dy(int index,int d)594 int  CDRGrid::dy (int index, int d)
595 {
596   if ( (index == INT_MAX) || (y(index) + d < 0) || (y(index) + d >= Y) )
597     return (INT_MAX);
598 
599   return (index + d*X);
600 }
601 
602 
603 
604 
605 // -------------------------------------------------------------------
606 // Modifier  :  "CDRGrid::dz ()".
607 
dz(int index,int d)608 int  CDRGrid::dz (int index, int d)
609 {
610   if ( (index == INT_MAX) || (z(index) + d < 0) || (z(index) + d >= Z) )
611     return (INT_MAX);
612 
613   return (index + d*XY);
614 }
615 
616 
617 
618 
619 // -------------------------------------------------------------------
620 // Destructor  :  "TMatrix::_CHollow::~_CHollow()".
621 
622 template<class __CNode__>
~_CHollow(void)623 TMatrix<__CNode__>::_CHollow::~_CHollow (void)
624 {
625     _CRow::iterator  itRow;
626   _CLayer::iterator  itLayer;
627 
628 
629   for (itLayer  = nodes.begin ();
630        itLayer != nodes.end   (); itLayer++) {
631     for (itRow  = itLayer->second.begin ();
632          itRow != itLayer->second.end   (); itRow++) {
633       delete itRow->second;
634     }
635   }
636 }
637 
638 
639 
640 
641 // -------------------------------------------------------------------
642 // Method  :  "TMatrix::_CHollow::add()".
643 
644 template<class __CNode__>
add(int x,int y)645 __CNode__ &TMatrix<__CNode__>::_CHollow::add (int x, int y)
646 {
647     _CRow::iterator  itRow;
648   _CLayer::iterator  itLayer;
649 
650 
651   itLayer = nodes.find (x);
652   if (itLayer == nodes.end ()) { nodes[x] = _CRow (); }
653 
654   itRow = nodes[x].find (y);
655   if (itRow == nodes[x].end ()) { nodes[x][y] = new __CNode__ (); }
656 
657   return (*(nodes[x][y]));
658 }
659 
660 
661 
662 
663 // -------------------------------------------------------------------
664 // Method  :  "TMatrix::_CHollow::get()".
665 
666 template<class __CNode__>
get(int x,int y)667 __CNode__ *TMatrix<__CNode__>::_CHollow::get (int x, int y)
668 {
669     _CRow::iterator  itRow;
670   _CLayer::iterator  itLayer;
671 
672 
673   itLayer = nodes.find (x);
674   if (itLayer == nodes.end ()) { return (NULL); }
675 
676   itRow = nodes[x].find (y);
677   if (itRow == nodes[x].end ()) { return (NULL); }
678 
679   return ((*itRow).second);
680 }
681 
682 
683 
684 
685 // -------------------------------------------------------------------
686 // Constructor  :  "TMatrix::TMatrix()".
687 
688 template<class __CNode__>
TMatrix(CDRGrid * drgrid)689 TMatrix<__CNode__>::TMatrix (CDRGrid *drgrid)
690   : _drgrid(drgrid)
691   , _zero  ()
692   , _grid  (new (__CNode__) [_drgrid->size])
693   , hole   ()
694 { }
695 
696 
697 
698 
699 // -------------------------------------------------------------------
700 // Destructor  :  "~TMatrix::TMatrix()".
701 
702 template<class __CNode__>
~TMatrix(void)703 TMatrix<__CNode__>::~TMatrix (void)
704 {
705   delete [] _grid;
706 }
707 
708 
709 
710 
711 // -------------------------------------------------------------------
712 // Accessor  :  "TMatrix::&operator[]".
713 
714 template<class __CNode__>
operator [](int index)715 __CNode__ &TMatrix<__CNode__>::operator[] (int index)
716 {
717   if (index < _drgrid->XY ) {
718     __CNode__ *node = _zero->get (_drgrid->x(index), _drgrid->y(index)) ;
719     if ( node != NULL ) return ( *node );
720   } else {
721     if (index < _drgrid->XYZ) return ( _grid[index - _drgrid->XY] );
722   }
723 
724   return ( hole );
725 }
726 
727 
728 
729 
730 // -------------------------------------------------------------------
731 // Modifier  :  "TMatrix::add ()".
732 
733 template<class __CNode__>
add(int index)734 __CNode__ &TMatrix<__CNode__>::add (int index)
735 {
736   if (index < _drgrid->XY) {
737     return ( _zero->add (_drgrid->x(index), _drgrid->y(index)) );
738   } else {
739     if (index < _drgrid->XYZ) return ( (*this)[index] );
740   }
741 
742   return ( hole );
743 }
744 
745 
746 
747 
748 // -------------------------------------------------------------------
749 // Module  :  "UNet.cpp".
750 
751 
752   // ---------------------------------------------------------------
753   // Duplicate terminal node exception.
754 
755   class dup_term : public exception {
756 
757     // Attributes.
758     public: string  name;
759     public: CNode  *node;
760 
761     // Constructor.
dup_term(string termName,CNode * dupNode)762     public: dup_term (string termName, CNode *dupNode) {
763               name = termName;
764               node = dupNode;
765             }
766 
767     // Overridables.
what() const768     public: virtual const char* what () const {
769               return ((char*)"Duplicated terminal node.");
770             }
771   };
772 
773 
774 
775 
776   // ---------------------------------------------------------------
777   // Terminal class.
778 
779   class CTerm {
780 
781     // Attributes.
782     public: int                      id;
783     public: string                   name;
784     public: list<CDRGrid::iterator>  nodes;
785     public: list<CRect>              rects;
786 
787     // Constructor.
788     public: CTerm (string termName, int ident);
789 
790     // Destructor.
791     public: ~CTerm (void);
792 
793     // Accessors.
794     public: int    distance (CTerm &other);
795     public: CTerm &nearest  (CTerm &term1, CTerm &term2);
796     public: CNode &lowest   (void);
797 
798     // Modifiers.
799     public: CNode *newaccess (int x, int y, int z, int ident, CNet *net) throw (dup_term);
800     public: void   newaccess (CRect &rect, int z, int ident, CNet *net);
801     public: void   lockalone (bool global=false);
802     public: void   setid     (int ident);
803 
804   };
805 
806 
807 
808 
809   // ---------------------------------------------------------------
810   // Duplicate net exception.
811 
812   class dup_net : public exception {
813 
814     // Attributes.
815     public: string  name;
816 
817     // Constructor.
dup_net(string netName)818     public: dup_net (string netName) { name = netName; }
819 
820     // Overridables.
what() const821     public: virtual const char* what () const {
822               return ((char*)"Duplicated net.");
823             }
824   };
825 
826 
827 
828 
829   // ---------------------------------------------------------------
830   // Unknown terminal exception.
831 
832   class term_unknown : public exception {
833 
834     // Attributes.
835     public: string  netName;
836     public: string  termName;
837 
838     // Constructor.
term_unknown(string nName,string tName)839     public: term_unknown (string nName, string tName) {
840               netName  = nName;
841               termName = tName;
842             }
843 
844     // Overridables.
what() const845     public: virtual const char* what () const {
846               return ((char*)"Unkown terminal.");
847             }
848   };
849 
850 
851 
852 
853   // ---------------------------------------------------------------
854   // Net class.
855 
856   class CNet {
857 
858     // Attributes.
859     public: int            pri;
860     public: string         name;
861     public: vector<CTerm*> terms;
862     public: CNode*         rtree;
863     public: CBB            bb;
864     public: int            size;
865     public: bool           external;
866 
867     // Constructor.
868     public: CNet (string netName="noname");
869 
870     // Destructor.
871     public: ~CNet (void);
872 
873     // Operator.
874     public: bool operator< (CNet &other);
875 
876     // Accessor.
global(void)877     public: bool global (void) { return (bb.hp >= 400); }
878 
879     // Modifiers.
880     public: void newaccess (string termName, int x, int y, int z);
881     public: void newaccess (string termName, CRect &rect, int z);
882     public: void order     (void);
883     public: void lockalone (void);
884     public: void locktree  (void);
885     public: void route     (void);
886     public: void unroute   (void);
887 
888     // Friends.
889     public: friend ostream &operator<< (ostream &o, CNet *self);
890 
891   };
892 
893   typedef  map<string, CNet>  MNet;
894 
895 
896 
897 
898 // -------------------------------------------------------------------
899 // Constructor  :  "CBB::CBB()".
900 
CBB(void)901 CBB::CBB (void)
902 {
903   x1 = INT_MAX;
904   y1 = INT_MAX;
905   x2 = 0;
906   y2 = 0;
907   hp = 0;
908 }
909 
910 
911 
912 
913 // -------------------------------------------------------------------
914 // Method  :  "CBB::merge()".
915 
merge(CCoord & coord)916 void CBB::merge (CCoord &coord)
917 {
918   x1 = min (x1, coord.x);
919   y1 = min (y1, coord.y);
920   x2 = max (x2, coord.x);
921   y2 = max (y2, coord.y);
922 
923   hp = (x2 - x1) + (y2 - y1);
924 }
925 
926 
927 
928 
929 // -------------------------------------------------------------------
930 // Friend of "CBB"  :  "&operator<<()".
931 
operator <<(ostream & o,CBB & self)932 ostream &operator<< (ostream &o, CBB &self)
933 {
934   o << "CBB (" << self.x1 << "," << self.y1 << ") ("
935     << self.x2 << "," << self.y2 << ") HP := " << self.hp;
936 
937   return (o);
938 }
939 
940 
941 
942 
943 // -------------------------------------------------------------------
944 // Method  :  "CMatrixPri::findfree()".
945 
findfree(int index)946 void  CMatrixPri::findfree (int index)
947 {
948   CDRGrid::iterator  coord;
949                 int  radius, i, j, cx, cy;
950                bool  freed;
951 
952 
953   freed  = false;
954   radius = 0;
955   cx     = _drgrid->x(index);
956   cy     = _drgrid->y(index);
957   coord  = _drgrid->origin;
958 
959   while (!freed) {
960     radius += 1;
961 
962     for (i = cx - radius; i < cx + radius + 1; i++) {
963       for (j = cy - radius; j < cy + radius + 1; j++) {
964         // Proccess only nodes of the ring.
965         // if ( (i > cx - radius) || (i < cx + radius) ) continue;
966         // if ( (j > cy - radius) || (j < cy + radius) ) continue;
967 
968         if ( !( (*_drgrid->nodes)[ coord.set(i,j,2) ].data.obstacle ) ) freed = true;
969 
970         (*this)[ coord.set(i,j,1) ] = (char)1;
971         (*this)[ coord.set(i,j,2) ] = (char)1;
972       }
973     }
974   }
975 }
976 
977 
978 
979 
980 // -------------------------------------------------------------------
981 // Method  :  "CMatrixPri::clear()".
982 
clear(void)983 void CMatrixPri::clear (void)
984 {
985   memset (_grid, (char)0, _drgrid->size);
986 
987   cleared = true;
988   offset  = 0;
989   delta   = 0;
990 }
991 
992 
993 
994 
995 // -------------------------------------------------------------------
996 // Method  :  "CMatrixPri::nextPri()".
997 
nextPri(char curpri)998 char CMatrixPri::nextPri (char curpri)
999 {
1000   return ((curpri > 1) ? (curpri >> 1) : 1);
1001 }
1002 
1003 
1004 
1005 
1006 // -------------------------------------------------------------------
1007 // Method  :  "CMatrixPri::load()".
1008 
load(CNet & net,bool global,int expand=0)1009 void CMatrixPri::load (CNet &net, bool global, int expand=0)
1010 {
1011    list<CDRGrid::iterator>::iterator   itNode, beginNode, endNode;
1012   queue<CDRGrid::iterator*>            queue1, queue2;
1013   queue<CDRGrid::iterator*>           *currentBorder, *nextBorder;
1014         CDRGrid::iterator             *pCoord, coord;
1015 
1016   char  currentPri, *pmap;
1017   int   x, y, z, nx, ny, nz, edge, id, ex, ey;
1018   bool  breakLoop;
1019 
1020 
1021   clear ();
1022 
1023   offset = net.pri;
1024   delta  = 0;
1025 
1026   currentBorder = &queue1;
1027   nextBorder    = &queue2;
1028   currentPri    = 64;
1029 
1030 
1031   // Expand the original BB if too small.
1032   ex = 0;
1033   ey = 0;
1034 
1035   if (net.bb.x2 - net.bb.x1 < 5) ex = 5;
1036   if (net.bb.y2 - net.bb.y1 < 5) ey = 5;
1037 
1038   if (expand) ex = ey = expand;
1039 
1040   _bb.x1 = max (0             , net.bb.x1 - ex);
1041   _bb.x2 = min (_drgrid->X - 1, net.bb.x2 + ex);
1042   _bb.y1 = max (0             , net.bb.y1 - ey);
1043   _bb.y2 = min (_drgrid->Y - 1, net.bb.y2 + ey);
1044 
1045 
1046   // Build the initials border lists : coordinates of the terminals.
1047   // The table doesn't have a z = 0 layer (never used for routing),
1048   //   so when a terminal on layer 0 is encountered, we queue the
1049   //   the coordinate on top in the next border queue.
1050   // That is, in the first step of the algorithm we fill both queue
1051   //   at the same time.
1052   // In the case of the map of a global signal (i.e. using z=3&4 for
1053   //   the time beeing, set to one the map points above the terminal
1054   //   in z=1&2, as they will not be set by the _bb loop.
1055 
1056   for (id = 0; id < net.size; id++) {
1057     beginNode = (net.terms[id])->nodes.begin ();
1058       endNode = (net.terms[id])->nodes.end ();
1059 
1060     for (itNode = beginNode; itNode != endNode; itNode++) {
1061       coord = *itNode;
1062 
1063       // Initial queues filling.
1064       if (coord.z() > 0) {
1065         (*this)[ coord ] = currentPri;
1066         currentBorder->push (new CDRGrid::iterator (coord));
1067 
1068         // Enable z=1 (in case of global signal, no effet otherwise).
1069         if (coord.z() < _drgrid->Z - 1) (*this)[ coord.dz(1) ] = (char)1;
1070 
1071         continue;
1072       }
1073 
1074       (*this)[ coord.dz(1) ] = nextPri (currentPri);
1075       nextBorder->push (new CDRGrid::iterator (coord));
1076 
1077       // Enable z=2 (in case of global signal, no effet otherwise).
1078       (*this)[ coord.dz(1) ] = (char)1;
1079 
1080       // Look if the upper node is blocked, in that case expand the
1081       // allowed zone till a non-blocked node is found.
1082 
1083       if ( (*_drgrid->nodes)[ coord ].data.obstacle ) findfree (coord);
1084     }
1085   }
1086 
1087 
1088   // Set to one all the points inside the enclosing box.
1089   // (except those in the initial queues)
1090   for (x = _bb.x1; x <= _bb.x2; x++) {
1091     for (y = _bb.y1; y <= _bb.y2; y++) {
1092       for (z = (global) ? 3 : 1; z < _drgrid->Z; z++) {
1093         pmap = & ( (*this)[ coord.set (x, y, z) ] );
1094         if (pmap && (!(*pmap))) *pmap = (char)1;
1095       }
1096     }
1097   }
1098 
1099 
1100   breakLoop  = false;
1101   currentPri = nextPri (currentPri);
1102 
1103   // And here we go!
1104   while (true) {
1105     // Checks if the current border is finished. If so swap it with the
1106     // nextBorder. If the current border is still empty, we are done.
1107     if (currentBorder->empty ()) {
1108       currentPri = nextPri (currentPri);
1109       swap (currentBorder, nextBorder);
1110 
1111       if (currentBorder->empty ()) {
1112         breakLoop = true;
1113       }
1114     }
1115     if (breakLoop) break;
1116 
1117     pCoord = currentBorder->front ();
1118     currentBorder->pop ();
1119 
1120     x = pCoord->x ();
1121     y = pCoord->y ();
1122     z = pCoord->z ();
1123 
1124     delete pCoord;
1125 
1126     for (edge = 0; edge < 6; edge++) {
1127       nx = x; ny = y; nz =z;
1128 
1129       // Look at all six neighbors.
1130       switch (edge) {
1131         case 0: nx -= 1; break;
1132         case 1: nx += 1; break;
1133         case 2: ny -= 1; break;
1134         case 3: ny += 1; break;
1135         case 4: nz -= 1; break;
1136         case 5: nz += 1; break;
1137       }
1138 
1139       pmap = & ( (*this)[ coord.set (nx, ny, nz) ] );
1140       if (pmap == &(this->hole)) { continue; }
1141 
1142       // Usable nodes have been set to at least one, if not skip it.
1143       if ( (pmap == NULL) || (*pmap == (char)0) ) continue;
1144 
1145       if (*pmap == (char)1) {
1146         *pmap = currentPri;
1147         // Push only nodes that are not of minimal priority.
1148         if (currentPri > (char)1)
1149           nextBorder->push (new CDRGrid::iterator (coord));
1150       }
1151     }
1152 
1153   }
1154 
1155 
1156   cleared = false;
1157 }
1158 
1159 
1160 
1161 
1162 // -------------------------------------------------------------------
1163 // Method  :  "CMatrixPri::cmp()".
1164 
cmp(int pri,int index)1165 bool CMatrixPri::cmp (int pri, int index)
1166 {
1167   char  mappri;
1168 
1169 
1170   mappri = (*this)[index];
1171 
1172   if (!mappri) return (true);
1173   if (!pri)    return (false);
1174 
1175   return (pri + 256 >= mappri + delta);
1176 }
1177 
1178 
1179 
1180 
1181 // -------------------------------------------------------------------
1182 // Friend  :  "&operator<<()".
1183 
operator <<(ostream & o,CMatrixPri & self)1184 ostream &operator<< (ostream &o, CMatrixPri &self)
1185 {
1186   CDRGrid::iterator  coord;
1187                 int  x, y, z;
1188 
1189   o << "cleared := " << self.cleared << "\n"
1190     << "offset  := " << self.offset  << "\n"
1191     << "delta   := " << self.delta   << "\n";
1192 
1193   coord = self._drgrid->origin;
1194 
1195   for (z = 1; z < self._drgrid->Z; z++) {
1196     o << "  (layer) z := " << z << "\n";
1197 
1198     for (y = 1; y <= self._drgrid->Y; y++) {
1199       o << "    ";
1200       for (x = 0; x < self._drgrid->X; x++) {
1201         o << setw(5) << (int)(self[
1202            coord.set (x, self._drgrid->Y - y, z)]);
1203       }
1204       o << "\n";
1205     }
1206   }
1207 
1208   return (o);
1209 }
1210 
1211 
1212 
main(int argc,char * argv[])1213 int main (int argc, char *argv[])
1214 {
1215 
1216   CDRGrid            *grid;
1217   CDRGrid::iterator   itNode, itNode2;
1218 
1219   try {
1220     //cout << &(*itNode) << endl;
1221 
1222     grid = new CDRGrid (10, 5, 3);
1223 
1224     itNode      = grid->origin;
1225     itNode2     = grid->origin;
1226 
1227     cout << "Browsing a row." << endl;
1228 
1229     for (; itNode.inside (); itNode.right ()) {
1230       cout << "  " << itNode
1231            << "\n  distance from origin := "
1232            << itNode.manhattan (itNode2) << endl;
1233     }
1234 
1235     cout << "Browsing a column." << endl;
1236 
1237     itNode = grid->origin;
1238     for (; itNode.inside (); itNode.up ()) {
1239       cout << "  " << itNode << endl;
1240     }
1241 
1242     cout << "Browsing layers." << endl;
1243 
1244     itNode = grid->origin;
1245     for (; itNode.inside (); itNode.top ()) {
1246       cout << "  " << itNode << endl;
1247     }
1248 
1249     itNode.manhattan (itNode2);
1250   }
1251 
1252   catch (e_matrix_iterator &e) {
1253     cerr << e.what () << endl;
1254   }
1255 }
1256