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