1 /************************************************************
3 ** COPYRIGHT (C) 1993 UNIVERSITY OF PITTSBURGH
4 ** COPYRIGHT (C) 1996 GANNON UNIVERSITY
7 ** This software is distributed on an as-is basis
8 ** with no warranty implied or intended. No author
9 ** or distributor takes responsibility to anyone
10 ** regarding its use of or suitability.
12 ** The software may be distributed and modified
13 ** freely for academic and other non-commercial
14 ** use but may NOT be utilized or included in whole
15 ** or part within any commercial product.
17 ** This copyright notice must remain on all copies
18 ** and modified versions of this software.
20 ************************************************************/
24 * As part of MS Thesis Work, S T Frezza, UPitt Engineering
25 * February, 1990 - Major revision July, 1990 - Incremental GR January, 1991
27 * This file contains the global and local routing functions associated with the
28 * SPAR schematics placer. It is based on the data-structures created by the
29 * parser (parse.c) and the placer (place.c), and is thus dependent upon: */
35 /* It is expected that all modules have been placed.
37 * The routing algorithm breaks the process into two stages, global and then local
38 * routing. To arrange for the channels used these two schemes, the modules are
39 * indidvidually inserted into a tile space (see cstitch.c) and the set of empty tile
40 * constitutes the available routing area.
43 * This process determines the tiles through which each net will pass. It is an
44 * expansion process, where the nodes that are expanded into are edges of tiles. The
45 * general gist is to do a first route, and then apply rip-up-&-reroute techniques to
46 * the most expensive of the routes, using cost-based expansion techniques. (Kern-like
48 * This is done such that every net is ripped up at least once. Nets are selected for
49 * rip-up if they happen to be in using the most congested asg_arc on along a net that is
50 * scheduled for rip-up.
53 * The global router will be a modified Korn [DAC '82]algorithm, somewhat similar to
54 * that used in the PI Place and Route system from MIT. The similarity is in the
55 * creation of routing channels (via the use of two parallel, 90 deg rotated corner-
56 * stitching structures). The differences lie in the handling of multi-terminal nets.
57 * These will be managed by drawing connecting lines to all points on the net, and
58 * collecting the set of cells through which they pass. All cells not on this list
59 * will be be given a higher cost, so as to speed the router up. These lines will
60 * extend from the target tiles that lay behind each of the terminals in question.
62 * Local Routing: see "local_route.c"
67 /* ---- Global Variables -------------------------------------------------------------*/
69 char net_under_study
[32] = "not in use";
70 char dfname
[40] = "temp";
72 net
*Net
= NULL
; /* Used as a temporary global */
74 FILE *df
, *vf
, *hf
; /* Where to dump the global route trace/debug info */
76 int currentPage
; /* The current page on which insertions are being made */
78 int (*set_congestion_value
)(); /* The congestion function being used */
81 /* --- forward reference -------------------------------------------------------------:*/
82 void write_local_route_to_file();
83 expnlist
*list_completed_subnetsA();
84 void prepare_tile_spaces();
88 void add_trail_copy();
89 trailist
*remove_trailA();
90 trailist
*remove_trailE();
92 tile
*locate_first_tile();
94 /*-------------------------------------------------------------------------------------
95 * Setup stuff - This creates the tile/arc data structures, and the expansion
96 * elements for a given placement.
97 *-------------------------------------------------------------------------------------
100 /*-------------------------------------------------------------------------------------*/
107 /*-------------------------------------------------------------------------------------*/
109 int contents_equivalentp_for_arcs(t1
, t2
)
112 asg_arc
*a1
= (asg_arc
*)t1
->this, *a2
= (asg_arc
*)t2
->this;
113 if (a1
->mod
== a2
->mod
) return(TRUE
);
117 /*-------------------------------------------------------------------------------------*/
118 /* return TRUE iff tile t is used. */
119 /*-------------------------------------------------------------------------------------*/
121 int solidp_for_arcs(t
)
124 asg_arc
*a
= (asg_arc
*)t
->this;
126 return((a
->mod
!= NULL
) ? TRUE
: FALSE
);
129 /*-------------------------------------------------------------------------------------*/
131 int emptyp_for_arcs(t
)
134 asg_arc
*a
= (asg_arc
*)t
->this;
136 return((a
->mod
!= NULL
) ? FALSE
: TRUE
);
139 /*-------------------------------------------------------------------------------------*/
141 asg_arc
*create_arc(t
, page
, modFlag
)
145 /* create a new arc structure, initialize it, and return it. */
149 /* Modifies the tile space by replacing the contents field with an arc struct. */
150 tarc
= (asg_arc
*)calloc(1, sizeof(asg_arc
));
151 tarc
->congestion
= 0;
153 tarc
->corners
= NULL
;
154 tarc
->nets
= NULL
; /* Where the 'whos used me' information goes */
155 tarc
->t
= t
; /* Store the tile pointer ( back pointer ) */
156 /* if this is a blank tile being transformed, save the module pointer. */
157 tarc
->mod
= (modFlag
== TRUE
) ? (module
*)t
->this : NULL
;
158 tarc
->vcap
= (page
== VERT
) ? t
->x_len
: t
->y_len
;
159 tarc
->hcap
= (page
== HORZ
) ? t
->x_len
: t
->y_len
;
160 tarc
->local
= tarc
->count
= 0;
162 for (i
=0; i
<HASH_SIZE
; i
++) tarc
->trails
[i
] = NULL
;
164 t
->this = (int *)tarc
; /* Replace the tile contents with the arc str. */
169 /*------------------------------------------------------------------------------------*/
174 /* Delete the contents and allocation for this arc: */
175 a
->nets
= (nlist
*)free_list(a
->nets
);
176 a
->corners
= (crnlist
*)free_list(a
->corners
);
181 /*------------------------------------------------------------------------------------*/
183 assign_tile_dimensions(m
, xPos
, yPos
, xLen
, yLen
)
185 int *xPos
, *yPos
, *xLen
, *yLen
;
187 switch(validate(m
->type
))
196 case XNOR
: *xPos
= m
->x_pos
- TERM_MARGIN
;
198 *xLen
= m
->x_size
+ 2 * TERM_MARGIN
;
201 case INPUT_SYM
: *xPos
= m
->x_pos
;
203 *xLen
= m
->x_size
+ TERM_MARGIN
;
206 case OUTPUT_SYM
: *xPos
= m
->x_pos
- TERM_MARGIN
;
213 *xPos
= m
->x_pos
- TERM_MARGIN
;
214 *yPos
= m
->y_pos
- TERM_MARGIN
;
215 *xLen
= m
->x_size
+ 2 * TERM_MARGIN
;
216 *yLen
= m
->y_size
+ 2 * TERM_MARGIN
;
221 /*------------------------------------------------------------------------------------*/
223 insert_all_modules(hroot
, vroot
, ml
)
227 /* This function inserts each listed tile into the tile space containing <hroot>. */
228 /* The tile is also inserted into the vertically-oriented space by reversing the
233 int xPos
, yPos
, xLen
, yLen
;
235 /* Reset the content-manging stuff for this round of tile dealings: */
237 contents_equivalentp
= std_contents_equivalentp
;
238 insert_contents
= std_insert_contents
;
239 manage_contents__hmerge
= manage_contents__vmerge
= null
;
240 manage_contents__hsplit
= manage_contents__vsplit
= null
;
241 manage_contents__dead_tile
= null
;
243 for (mll
= ml
; mll
!= NULL
; mll
= mll
->next
)
245 mll
->this->htile
= mll
->this->vtile
= NULL
; /* Zero out the tile pointers */
247 assign_tile_dimensions(mll
->this, &xPos
, &yPos
, &xLen
, &yLen
);
249 /* Include a buffer around the modules for the terminals */
250 t
= insert_tile(hroot
, xPos
, yPos
, xLen
, yLen
, mll
->this);
251 mll
->this->htile
= t
; /* save the horiz tile pointer
252 for cross-reference */
255 fprintf(stderr
, "ERROR: %s module %s did not insert into horz tilespace\n",
256 mll
->this->type
, mll
->this->name
, mll
->this);
260 t
= insert_tile(vroot
, yPos
, xPos
, yLen
, xLen
, mll
->this);
261 mll
->this->vtile
= t
; /* save the vert tile pointer for
265 fprintf(stderr
, "ERROR: %s module %s did not insert into vert tilespace\n",
266 mll
->this->type
, mll
->this->name
, mll
->this);
270 mll
->this->placed
= FALSE
; /* Reuse of flag, now used for printing */
272 } /* No error checking */
274 /*------------------------------------------------------------------------------------*/
276 distribute_corner_list(owner
, partner
)
277 asg_arc
*owner
, *partner
; /* <owner> contains <corners>, <partner>s ->corners
280 /* Redistribute the corners contained in <corners> amongst the two tiles such that
281 the range limitations of the various points are observed. Correct the
282 tile/arc pointers within the corner structures themselves. */
284 crnlist
*cl
, *corners
= (crnlist
*)rcopy_list(owner
->corners
);
286 for (cl
= corners
; cl
!= NULL
; cl
= cl
->next
)
288 if (corner_falls_in_arc_p(cl
->this, owner
) == FALSE
)
290 pull_corner_from_arc(cl
->this, owner
);
292 if ((partner
!= NULL
) && (corner_falls_in_arc_p(cl
->this, partner
) == TRUE
))
294 add_corner_to_arc(cl
->this, partner
);
300 /*------------------------------------------------------------------------------------*/
302 consolodate_corner_list(taker
, giver
)
303 asg_arc
*taker
, *giver
;
305 /* Redistribute the corners contained in <giver> into <taker>.
306 The range limitations of the various points are observed. Correct the
307 tile/arc pointers within the corner structures themselves. */
311 for (cl
= giver
->corners
; cl
!= NULL
; cl
= cl
->next
)
313 if (corner_falls_in_arc_p(cl
->this, taker
) == TRUE
)
315 add_corner_to_arc(cl
->this, taker
);
317 pull_corner_from_arc(cl
->this, taker
);
321 /*------------------------------------------------------------------------------------*/
323 int definite_overlap_p(a1
, a2
, b1
, b2
)
326 if ((a1
< b2
) && (a2
> b1
)) return(TRUE
);
330 /*------------------------------------------------------------------------------------*/
332 int tile_contacts_tile_p(t1
, t2
)
335 /* Returns TRUE iff <t1> intersects <t2>. It is assumed that the two tiles
336 are from opposite page orientations. */
338 if ((definite_overlap_p(t1
->x_pos
, t1
->x_pos
+ t1
->x_len
,
339 t2
->y_pos
, t2
->y_pos
+ t2
->y_len
) == TRUE
) &&
340 (definite_overlap_p(t2
->x_pos
, t2
->x_pos
+ t2
->x_len
,
341 t1
->y_pos
, t1
->y_pos
+ t1
->y_len
) == TRUE
))
348 /*------------------------------------------------------------------------------------*/
350 int valid_trail_p(tr
)
353 /* Check the given trail <tr> for consitency. */
359 for (tl
= tr
->tr
; tl
!= NULL
; tl
= tl
->next
)
361 if ((tl
== tr
->tr
) && /* First tile on list && */
362 (tr
->jEx
!= NULL
)) /* It's a completed trail */
364 termTile
= initial_move(tr
->jEx
, HORZ
);
365 if (termTile
!= tl
->this)
371 if (tl
->next
!= NULL
)
373 if (tile_contacts_tile_p(tl
->this, tl
->next
->this) == FALSE
)
378 else /* At the beginning of the trail, so check to see that it touches
379 the terminial listed for tr->ex->t */
381 termTile
= initial_move(tr
->ex
, HORZ
);
382 if (termTile
!= tl
->this)
391 /*------------------------------------------------------------------------------------*/
393 int check_trail_p(tr
, org
, rep
)
397 /* Check the given trail <tr> for the tile <org>. For the instance of <org>,
398 replace it with <rep> and check to see that the trail is still valid, that
399 is that the (two) neighbor(s) of <org> can legally reach <rep>. */
400 /* This simply insures that the trail works up to the point where the
401 replacement occurs. */
406 int tx
, ty
, foundIt
= FALSE
, damnThingFits
= 0;
408 if (tr
->tr
->this == org
) damnThingFits
= 1; /* <org> is at head of list */
410 for (tl
= tr
->tr
; tl
!= NULL
; tl
= tl
->next
)
411 { /* This first check is a validation check */
412 if ((tl
== tr
->tr
) && /* First tile on list && */
413 (tr
->jEx
!= NULL
)) /* It's a completed trail */
415 termTile
= initial_move(tr
->jEx
, HORZ
);
416 if (((tl
->this == org
) && (rep
!= termTile
)) ||
417 ((tl
->this != org
) && (termTile
!= tl
->this)))
423 if (tl
->next
!= NULL
)
425 if ((tl
->next
->this == org
) &&
426 (tile_contacts_tile_p(tl
->this, rep
) == TRUE
)) damnThingFits
+=1;
427 else if (tl
->this == org
)
430 if (tile_contacts_tile_p(tl
->next
->this, rep
) == TRUE
)
433 else if (tile_contacts_tile_p(tl
->this, tl
->next
->this) == FALSE
)
440 termTile
= initial_move(tr
->ex
, HORZ
);
442 { /* <org> is at tail end of list */
444 if (termTile
== rep
) damnThingFits
+= 1;
446 else if (termTile
!= tl
->this)
454 fprintf(stderr
, "Tile 0x%x got lost (wrt trail 0x%x)\n", org
, tr
);
456 return (((foundIt
== TRUE
) && (damnThingFits
>= 2)) ? TRUE
: FALSE
);
459 /*------------------------------------------------------------------------------------*/
460 /*------------------------------------------------------------------------------------*/
462 trail
*enumerate_trail(pTrail
, org
, rep
)
466 /* Replicate the given trail with the <org> tile replaced with the <rep> tile.
467 Do no error checking or costing */
468 trail
*t
= copy_trail(pTrail
);
469 repl_item(org
, rep
, t
->tr
);
473 /*------------------------------------------------------------------------------------*/
475 void manage_trails_for_merge(amoeba
, food
)
476 asg_arc
*amoeba
, *food
;
478 /* This is to merge/validate/correct the trails collected in the <amoeba> arc;
479 The appropriate trails are swiped from the <food> arc. The 'food' arc
480 is about to be swallowed up... */
482 /* Also builds the ->nets list for the <amoeba> arc, deleting that for the <food>
483 arc. The congestion values are appropriately set.*/
486 trailist
*trl
, *temp
;
492 manage_trails_for_merge(food
, amoeba
);
495 else return; /* Bad call... */
497 else if (food
== NULL
) return; /* Trivial Case */
499 amoeba
->nets
= (nlist
*)free_list(amoeba
->nets
);
501 /* Walk through the table in <food>, copying whatever is of use, and destroying
502 the rest. When completed, <food>'s hash table should get nuked. */
503 for (i
=0; i
<HASH_SIZE
; i
++)
505 temp
= (trailist
*)rcopy_ilist(food
->trails
[i
]);
506 for (trl
= temp
; trl
!= NULL
; trl
= trl
->next
)
508 if (check_trail_p(trl
->this, food
->t
, amoeba
->t
) == TRUE
)
510 repl_item(food
->t
, amoeba
->t
, t
->tr
);
511 insert_trailA(trl
->this, food
);
512 pushnew(t
->ex
->n
, &food
->nets
);
514 remove_trailA(trl
->this, food
);
516 temp
= (trailist
*)free_ilist(temp
);
517 food
->trails
[i
] = (trailist
*)free_ilist(food
->trails
[i
]);
521 /*------------------------------------------------------------------------------------*/
523 trlist
*manage_trails_for_split(parent
, sibling
, pFlag
)
524 asg_arc
*parent
, *sibling
;
525 int pFlag
; /* If TRUE, then modify <parent> */
527 /* This is to validate/correct the trails collected in the <parent> arc;
528 The appropriate trails are then recreated for the <sibling> arc. */
530 /* Also rebuilds the ->nets list for each of the arcs, and resets the congestion
533 /* The <pFlag> acts as a delayer; The clean-up for the <parent> arc is only
534 evaluated if the flag is set. */
538 trailist
*temp
, *trash
, *trl
;
539 trlist
*valid
= NULL
;
545 valid
= manage_trails_for_split(sibling
, parent
, pFlag
);
548 else return; /* Bad call... */
552 parent
->nets
= (nlist
*)free_list(parent
->nets
);
554 if ((sibling
== NULL
) && (pFlag
== TRUE
))
556 /* Any trail that connects <p> validly (ie, now that p has been changed)
557 is still valid, and should remain in the table to be rehashed.
558 Any trail that does not connect should be nuked.
560 This is a selective rehash of the arc. */
561 for (i
=0; i
<HASH_SIZE
; i
++)
563 temp
= (trailist
*)rcopy_ilist(parent
->trails
[i
]);
565 for (trl
= temp
; trl
!= NULL
; trl
= trl
->next
)
567 if (check_trail_p(trl
->this, p
, p
) == TRUE
)
570 t
->cost
= trail_cost(t
);
572 pushnew(t
->ex
->n
, &parent
->nets
);
573 if (valid_trail_p(t
) == TRUE
) push(t
, &valid
);;
575 else if (pFlag
== TRUE
)
577 delete_trail(trl
->this);
580 temp
= (trailist
*)free_ilist(temp
);
585 /* Any trail that connects <s> validly (when <p> usage is replaced with <s>)
586 is still valid, and should be added to <sibling>'s table.
587 Any trail that does not connect should be ignored. */
590 sibling
->nets
= (nlist
*)free_list(sibling
->nets
);
592 for (i
=0; i
<HASH_SIZE
; i
++)
594 temp
= (trailist
*)rcopy_ilist(parent
->trails
[i
]);
596 for (trl
= temp
; trl
!= NULL
; trl
= trl
->next
)
598 if ((check_trail_p(trl
->this, p
, p
) == TRUE
) &&
602 t
->cost
= trail_cost(t
);
604 pushnew(t
->ex
->n
, &parent
->nets
);
605 if (valid_trail_p(t
) == TRUE
) push(t
, &valid
);;
607 if (check_trail_p(trl
->this, p
, s
) == TRUE
)
609 t
= enumerate_trail(trl
->this, p
, s
);
610 t
->cost
= trail_cost(t
);
612 if (valid_trail_p(t
) == TRUE
) push(t
, &valid
);;
615 else /* Blow the trail away. It is now been proven invalid. */
617 if (check_trail_p(trl
->this, p
, s
) == TRUE
)
619 t
= enumerate_trail(trl
->this, p
, s
);
620 t
->cost
= trail_cost(t
); /* can't break ties if <trl->this> is */
621 if (pFlag
== TRUE
) delete_trail(trl
->this);
622 add_trail_copy(t
); /* addition */
623 if (valid_trail_p(t
) == TRUE
) push(t
, &valid
);;
625 else if (pFlag
== TRUE
)
627 delete_trail(trl
->this);
631 temp
= (trailist
*)free_ilist(temp
);
637 /*------------------------------------------------------------------------------------*/
638 /*------------------------------------------------------------------------------------*/
640 void manage_arc_during_hmerge(left
, right
)
643 /* <left> will remain, while <right> is destroyed. All pertinent info from <right>
644 needs to be copied into <left>.
646 asg_arc
*lArc
, *rArc
;
650 fprintf(stderr
, "manage_arc_during_hmerge called with NULL arg...\n");
651 return; /* probably very bad... */
653 else if (right
!= NULL
)
655 return; /* Problem ?? Hard to say. */
657 if (solidp_for_arcs(left
) == TRUE
)
659 fprintf(stderr
, "problem in manage_arc_during_hmerge\n");
663 lArc
= (asg_arc
*)left
->this;
664 rArc
= (asg_arc
*)right
->this;
666 lArc
->hcap
= (currentPage
== HORZ
) ? left
->x_len
: left
->y_len
;
667 lArc
->vcap
= (currentPage
== VERT
) ? left
->x_len
: left
->y_len
;
668 lArc
->local
+= rArc
->local
;
669 lArc
->count
+= rArc
->count
;
671 consolodate_corner_list(lArc
, rArc
);
672 manage_trails_for_merge(lArc
, rArc
);
675 /*------------------------------------------------------------------------------------*/
677 void manage_arc_during_vmerge(bottom
, top
)
680 asg_arc
*bArc
, *tArc
;
684 fprintf(stderr
, "manage_arc_during_hmerge called with NULL arg...\n");
685 return; /* probably very bad... */
687 else if (top
!= NULL
)
689 return; /* Problem ?? Hard to say. */
691 if (solidp_for_arcs(bottom
) == TRUE
)
693 fprintf(stderr
, "problem in manage_arc_during_vmerge\n");
697 bArc
= (asg_arc
*)bottom
->this;
698 tArc
= (asg_arc
*)top
->this;
700 bArc
->hcap
= (currentPage
== HORZ
) ? bottom
->x_len
: bottom
->y_len
;
701 bArc
->vcap
= (currentPage
== VERT
) ? bottom
->x_len
: bottom
->y_len
;
702 bArc
->local
+= tArc
->local
;
703 bArc
->count
+= tArc
->count
;
705 consolodate_corner_list(bArc
, tArc
);
706 manage_trails_for_merge(bArc
, tArc
);
709 /*------------------------------------------------------------------------------------*/
711 void manage_arc_during_hsplit(left
, right
)
714 asg_arc
*a
, *cArc
, *pArc
;
716 trlist
*collectedTrails
= NULL
;
718 /* Create the arc for the <child> arc and tie it in: */
719 pArc
= (asg_arc
*)left
->this;
720 cArc
= create_arc(right
, currentPage
, FALSE
);
721 pArc
->hcap
= (currentPage
== HORZ
) ? left
->x_len
: left
->y_len
;
722 pArc
->vcap
= (currentPage
== VERT
) ? left
->x_len
: left
->y_len
;
723 cArc
->local
= pArc
->local
;
724 cArc
->count
= pArc
->count
;
726 distribute_corner_list(pArc
, cArc
);
727 collectedTrails
= manage_trails_for_split(pArc
, cArc
, TRUE
);
729 if ((debug_level
== 4) && (collectedTrails
!= NULL
))
731 fprintf(stderr
, "\narc for tiles [%x]c ", right
);
733 fprintf(stderr
, " & [%x]p ", left
);
735 fprintf(stderr
," contains %d trails: \n", list_length(collectedTrails
));
736 dump_trails(collectedTrails
);
740 /*------------------------------------------------------------------------------------*/
742 void manage_arc_during_vsplit(top
, bot
)
745 asg_arc
*a
, *cArc
, *pArc
;
747 trlist
*collectedTrails
= NULL
;
749 /* Create the arc for the <child> arc and tie it in: */
750 pArc
= (asg_arc
*)top
->this;
751 cArc
= create_arc(bot
, currentPage
, FALSE
);
752 pArc
->hcap
= (currentPage
== HORZ
) ? top
->x_len
: top
->y_len
;
753 pArc
->vcap
= (currentPage
== VERT
) ? top
->x_len
: top
->y_len
;
754 cArc
->local
= pArc
->local
;
755 cArc
->count
= pArc
->count
;
757 distribute_corner_list(pArc
, cArc
);
758 collectedTrails
= manage_trails_for_split(pArc
, cArc
, TRUE
);
760 if ((debug_level
== 4) && (collectedTrails
!= NULL
))
762 fprintf(stderr
, "\nasg_arc for tiles [%x] ", bot
);
764 fprintf(stderr
, " & [%x] ", top
);
766 fprintf(stderr
," contains %d trails: \n", list_length(collectedTrails
));
767 dump_trails(collectedTrails
);
771 /*------------------------------------------------------------------------------------*/
773 void manage_arcs_for_modified_tiles(tilePairList
)
776 /* Given a list of tilists in the form (child, parent), correct the arcs in
777 each. This essentially means checking all trails contained in each of the
778 <parent> tiles, and then checking each trail for all combinations of variations.
779 this is a lot of checking, but typically not a lot of work. Typical trails
780 will have only one affected tile, and the rare trail will have two.
782 given the lists (a,b), (c,d),(e,a), (f,d), the following arrangement should
783 be made: (in order!!)
784 All occurances of <b> map into two lists, ...a... and ...b...
785 All occurances of <d> map into two lists, ...d... and ...c...
786 All occurances of <a> map into two lists, ...a... and ...e...
787 All occurances of <d> map into two lists, ...d... and ...f...
788 Note that this implies that the <d>'s actually form many more combinations. */
791 tile
*parent
, *child
;
792 tilist
*tl
, *pr
, *tilesTouched
= NULL
;
793 asg_arc
*a
, *cArc
, *pArc
, *oldArc
;
795 trlist
*trl
, *enumTrails
= NULL
, *collectedTrails
= NULL
;
796 trlist
*remove_all_trails_from_arc();
799 (1) Collect all the trails from the parent arc (Remove them from the arcs)...
800 (1a)Create arcs for the child tiles.
801 (2) Then enumerate the trails, as per the <tilePairList> ordering...
802 (3) Given this (enumerated) list of trails, validate each trail...
803 (4) reinsert each trail into the arcspace...
804 (5) Clean up list pointers.
807 /* Generate the enuimerated trlist: (Items (1) & (2) */
808 for(l
= tilePairList
; l
!= NULL
; l
= l
->next
)
810 pr
= (tilist
*)l
->this;
811 parent
= pr
->next
->this; child
= pr
->this;
813 /* Create the arc for the <child> arc and tie it in: */
814 pArc
= (asg_arc
*)parent
->this;
815 oldArc
= (asg_arc
*)child
->this;
816 cArc
= create_arc(child
, currentPage
, FALSE
);
817 cArc
->local
= oldArc
->local
;
818 cArc
->count
= oldArc
->count
;
819 distribute_corner_list(oldArc
, cArc
);
820 distribute_corner_list(pArc
, cArc
);
822 collectedTrails
= remove_all_trails_from_arc(parent
->this);
824 /* Comb through the trails that have already been enumerated; <parent> may
825 or may not be a part of these trails */
826 for (trl
= enumTrails
; trl
!= NULL
; trl
= trl
->next
)
828 if (member_p(parent
, trl
->this->tr
, identity
) == TRUE
)
830 tr
= enumerate_trail(trl
->this, parent
, child
);
831 push(tr
, &enumTrails
);
835 /* enumerate all of the <collectedTrails>, as <parent> is a member of each of
837 for (trl
= collectedTrails
; trl
!= NULL
; trl
= trl
->next
)
839 tr
= enumerate_trail(trl
->this, parent
, child
);
840 push(tr
, &enumTrails
);
843 /* Combine to form the complete enumeration list. */
844 enumTrails
= (trlist
*)append_list(enumTrails
, collectedTrails
);
846 pushnew(parent
, &tilesTouched
); pushnew(child
, &tilesTouched
);
849 /* Validate these trails, deleting the bad ones, and inserting the
850 good ones. (Items 3 & 4) */
851 for (trl
= enumTrails
; trl
!= NULL
; trl
= trl
->next
)
854 if (valid_trail_p(tr
) == TRUE
)
856 tr
->cost
= trail_cost(tr
);
865 /* finally, (5) Cleanup the list pointers... */
866 free_list(enumTrails
);
867 free_list(tilesTouched
);
870 /*------------------------------------------------------------------------------------*/
871 /*------------------------------------------------------------------------------------*/
873 void manage_arc_for_new_tile(new)
875 { /* This tile was just created... */
876 asg_arc
*q
= create_arc(new, currentPage
, TRUE
);
879 /*------------------------------------------------------------------------------------*/
881 void manage_arc_for_dead_tile(old
)
883 { /* This tile is about to go away... */
884 /* Check to see that it is not something important like a root tile... */
885 asg_arc
*a
= (asg_arc
*)old
->this;
887 if(routingRoot
[a
->page
][currentPage
] == old
)
889 if (old
->rt
!= NULL
) routingRoot
[a
->page
][currentPage
] = old
->rt
;
890 else if (old
->tr
!= NULL
) routingRoot
[a
->page
][currentPage
] = old
->tr
;
891 else if (old
->lb
!= NULL
) routingRoot
[a
->page
][currentPage
] = old
->lb
;
892 else if (old
->bl
!= NULL
) routingRoot
[a
->page
][currentPage
] = old
->bl
;
895 fprintf(stderr
, "dying tile about to blow away rootTile[%d][%d]...\n",
896 a
->page
, currentPage
);
899 /* Trash everything in the arc: */
903 /*------------------------------------------------------------------------------------*/
905 void manage_arc_for_copied_tile(child
, parent
)
906 tile
*child
, *parent
;
908 /* <new>->this points to the arc for the tile this was copied from, so be careful */
909 asg_arc
*cArc
, *pArc
= (asg_arc
*)parent
->this, *oldArc
= (asg_arc
*)child
->this;
910 tile
*oldTile
= oldArc
->t
;
913 cArc
= create_arc(child
, currentPage
, FALSE
);
914 cArc
->local
= oldArc
->local
;
915 cArc
->count
= oldArc
->count
;
916 distribute_corner_list(oldArc
, cArc
);
917 distribute_corner_list(pArc
, cArc
);
919 /* To handle the trails, probably need to assume that the corner stitches for
920 <top> and <bottom> are correct, which is not a safe assumption, I THINK.
921 This could be a very critical problem. */
923 q
= manage_trails_for_split(oldArc
, cArc
, FALSE
);
925 if ((debug_level
== 4) && (q
!= NULL
))
927 fprintf(stderr
, "\narc for tiles [%x] ", child
);
929 fprintf(stderr
, " & [%x] ", oldTile
);
931 fprintf(stderr
," contains %d trails: \n", list_length(q
));
936 /*------------------------------------------------------------------------------------*/
938 void manage_arc_for_clipped_tile(copy
)
941 /* This tile has been modified, and is now stable. Correct the contents to
942 reflect this change. */
943 asg_arc
*qArc
= (asg_arc
*)copy
->this;
946 distribute_corner_list(qArc
, NULL
);
947 q
= manage_trails_for_split(qArc
, NULL
, TRUE
);
948 if ((debug_level
== 4) && (q
!= NULL
))
950 fprintf(stderr
, "arc for tile [%x] ", copy
);
952 fprintf(stderr
, " contains %d trails: \n", list_length(q
));
957 /*------------------------------------------------------------------------------------*/
959 void insert_contents_for_arc(t
, m
)
963 /* Given the tile <t> that is part of the modified tile space, insert <m> into
964 the arc structure, and return said structure;
966 asg_arc
*a
= (arc
*)t
->this;
970 /*------------------------------------------------------------------------------------*/
973 mlist
*ml
; /* List of modules being added */
974 int p
; /* the page being dealt with */
976 /* Designed for use on modified tile spaces. */
977 /* This function inserts each listed tile a->trails[index]
978 into the tile space containing routingRoot[HORZ][p]. */
979 /* The tile is also inserted into the vertically-oriented space by reversing
980 the x,y ordering and inserting into the space containing tile
981 routingRoot[VERT][p].
983 These two globals must be used, as they can be changed as modifications occur
984 within the tile spaces during the calls to "insert_tile." */
989 int xPos
, yPos
, xLen
, yLen
;
991 /* Setup all of the specialized functions for handling complex colors in
993 /* See "cstitch.h" and "cstitch.c" for the specs and usage of thes functions. */
994 manage_contents__hmerge
= manage_arc_during_hmerge
;
995 manage_contents__vmerge
= manage_arc_during_vmerge
;
996 manage_contents__hsplit
= manage_arc_during_hsplit
;
997 manage_contents__vsplit
= manage_arc_during_vsplit
;
998 manage_contents__dead_tile
= manage_arc_for_dead_tile
;
1000 solidp
= solidp_for_arcs
;
1001 contents_equivalentp
= contents_equivalentp_for_arcs
;
1002 insert_contents
= insert_contents_for_arc
;
1004 for (mll
= ml
; mll
!= NULL
; mll
= mll
->next
)
1006 if (debug_level
== 4)
1008 fprintf(stderr
, "module %s being added to the Horizontal Page:\n",
1013 /* Include a buffer around the modules for the terminals */
1014 assign_tile_dimensions(mll
->this, &xPos
, &yPos
, &xLen
, &yLen
);
1016 t
= insert_tile(routingRoot
[HORZ
][p
], xPos
, yPos
, xLen
, yLen
, mll
->this);
1017 mll
->this->htile
= t
; /* save the horiz tile pointer
1018 for cross-reference */
1021 fprintf(stderr
, "ERROR: %s module %s did not insert into horz tilespace\n",
1022 mll
->this->type
, mll
->this->name
, mll
->this);
1025 if (debug_level
== 4)
1027 fprintf(stderr
, "inserted @ %x...", t
);
1029 fprintf(stderr
, "\nmodule <%s> being added to the Vertical Page:\n",
1034 t
= insert_tile(routingRoot
[VERT
][p
], yPos
, xPos
, yLen
, xLen
, mll
->this);
1035 mll
->this->vtile
= t
; /* save the vert tile pointer for
1039 fprintf(stderr
, "ERROR: %s module %s did not insert into vert tilespace\n",
1040 mll
->this->type
, mll
->this->name
, mll
->this);
1044 mll
->this->placed
= FALSE
; /* Reuse of flag, now used for printing */
1045 if (debug_level
== 4)
1047 fprintf(stderr
, "inserted @ %x...", t
);
1049 fprintf(stderr
,"\n");
1052 } /* No error checking */
1054 /*-------------------------------------------------------------------------------------*/
1056 reform_tile_space(Tlist
, page
)
1058 int page
; /* orientation of the tile-space */
1060 /* Reform the tile space such that the tile contents point to arcs, and the
1061 arc->t slots point to the original tile contents (either NULL or a Module
1067 for (tl
= Tlist
; tl
!= NULL
; tl
= tl
->next
)
1069 /* Save the module pointer from the communist (unreformed) tile */
1070 tarc
= create_arc(tl
->this, page
, TRUE
);
1074 /*-------------------------------------------------------------------------------------*/
1075 /*-------------------------------------------------------------------------------------*/
1077 int not_source_p(ex
)
1080 /* Return TRUE if the given expansion is associated with a source terminal */
1081 if (ex
->t
->type
== IN
) return(TRUE
);
1085 /*------------------------------------------------------------------------*/
1087 int identity(exp1
, exp2
)
1090 return ((int)exp1
== (int)exp2
);
1093 /*---------------------------------------------------------------------------------*/
1094 /* TRAIL MANIPULATION FUNCTIONS - */
1095 /*---------------------------------------------------------------------------------*/
1097 /*------- Manage the Hash table in the expn structure: ----------------------------*/
1102 /* Given a trail, hash your way to it */
1104 unsigned hashval
= (unsigned)(((int)tr
->ex
+ ((int)tr
->ex
% 3)) % HASH_SIZE
);
1109 /*------------------------------------------------------------------------------------*/
1111 trailist
*lookup_trailE(tr
, ex
)
1115 /* This function returns a pointer to the trailist structure where the given
1116 trail <tr> should be stored. */
1117 trailist
*trl
= ex
->queue
[ hashE(tr
) ];
1119 if (find_indexed_element(tr
->cost
, trl
) != NULL
) return(trl
);
1123 /*------------------------------------------------------------------------------------*/
1125 int note_tiles_added(trailToCheck
, ex
)
1126 trail
*trailToCheck
;
1129 /* This is to maintain the ->seen list in <ex> */
1131 tile
*lastTileAdded
; /* Used to check if an addition has been made... */
1132 tilist
*tilesToCheck
= trailToCheck
->tr
;
1135 if (trailToCheck
->ex
== ex
)
1137 for (tl
= tilesToCheck
; tl
!= NULL
; tl
= tl
->next
)
1139 pushnew(tl
->this, &ex
->seen
);
1140 lastTileAdded
= ex
->seen
->this;
1141 if (tl
->this != lastTileAdded
) /* If this tile has been 'seen'already, */
1142 { /* assume the rest of the tiles on the list */
1143 break; /* have been as well. . This works on the */
1144 } /* assumtion that the last tile in the list */
1145 } /* is a source tile for <ex>. */
1147 else /* Otherwise, who knows? Check 'em all... */
1149 for (tl
= tilesToCheck
; tl
!= NULL
; tl
= tl
->next
) pushnew(tl
->this, &ex
->seen
);
1153 /*------------------------------------------------------------------------------------*/
1155 int insert_trailE(tr
, ex
)
1159 /* This installs <tr> into the hashtable in <ex> */
1160 int q
, hashval
= hashE(tr
);
1162 if ((ex
->queue
[ hashval
] != NULL
) &&
1163 (ex
->queue
[ hashval
]->this->cost
== tr
->cost
))
1165 /* Deal with the race condition: */
1166 if (break_cost_tie(ex
->queue
[hashval
]->this, tr
) == TRUE
) tr
->cost
+= 1;
1167 else ex
->queue
[hashval
]->this->cost
+= 1;
1169 q
= ordered_ilist_insert(tr
, tr
->cost
, &ex
->queue
[ hashE(tr
) ]);
1171 note_tiles_added(tr
, ex
); /* Record that this tile has been seen */
1175 /*------------------------------------------------------------------------------------*/
1177 trailist
*remove_trailE(tr
, ex
)
1181 /* This removes the given trail from the hash table in <ex>. */
1182 int index
= hashE(tr
);
1184 expnlist
*exl
, *newSibList
, *oldSibList
= NULL
;
1185 trlist
*trl
, *newConnList
;
1186 trail
*q
= (trail
*)irem_item(tr
, &ex
->queue
[index
], NULL
);
1188 /* Maintain the ->siblings and ->connections lists: */
1189 for (trl
= ex
->connections
; trl
!= NULL
; trl
= trl
->next
)
1191 if (trl
->this == tr
)
1193 rem_item(tr
, &ex
->connections
);
1194 rem_item(ex
, &ex
->siblings
);
1195 newSibList
= ex
->siblings
;
1196 newConnList
= ex
->connections
;
1197 push(ex
, &oldSibList
);
1199 for (exl
= newSibList
; exl
!= NULL
; exl
= exl
->next
)
1201 exl
->this->siblings
= newSibList
; /* may not have changed */
1202 exl
->this->connections
= newConnList
;
1204 ex
->siblings
= oldSibList
;
1207 return(ex
->queue
[index
]);
1210 /*------------------------------------------------------------------------------------*/
1212 trail
*best_trailE(ex
)
1215 /* This pops the best trail off of the hash table in <ex>: */
1216 int i
, bestIndex
= FALSE
;
1217 int bestVal
= FALSE
;
1218 for (i
=0; i
<HASH_SIZE
; i
++)
1220 if ((ex
->queue
[i
] != NULL
) &&
1221 ((bestVal
== FALSE
) || (ex
->queue
[i
]->index
<= bestVal
)))
1224 bestVal
= ex
->queue
[i
]->index
;
1227 if (bestIndex
== FALSE
) return(NULL
);
1228 else return((trail
*)ipop(&ex
->queue
[bestIndex
]));
1231 /*------------------------------------------------------------------------------------*/
1233 trail
*examine_best_trailE(ex
)
1236 /* simply returns the pointer to the best_trail for examination */
1237 int i
, bestIndex
= FALSE
;
1238 int bestVal
= FALSE
;
1240 for (i
=0; i
<HASH_SIZE
; i
++)
1242 if ((ex
->queue
[i
] != NULL
) &&
1243 ((bestVal
== FALSE
) || (ex
->queue
[i
]->this->cost
<= bestVal
)))
1246 bestVal
= ex
->queue
[i
]->this->cost
;
1249 if (bestIndex
== FALSE
) return(NULL
);
1250 else return((trail
*)(ex
->queue
[bestIndex
]->this));
1253 /*------------------------------------------------------------------------------------*/
1255 void pull_trail_from_all_arcs(t
)
1258 /* Nuke the little commie: */
1260 for (tl
= t
->tr
; tl
!= NULL
; tl
= tl
->next
)
1262 remove_trailA(t
, (asg_arc
*)tl
->this->this); /* Pull from arc hash table */
1267 /*------------------------------------------------------------------------------------*/
1269 void delete_trail(t
)
1272 /* Nuke the little commie: */
1273 pull_trail_from_all_arcs(t
); /* Pull from arc hash tables */
1274 remove_trailE(t
, t
->ex
); /* Pull from expn hash table */
1278 /*------------------------------------------------------------------------------------*/
1279 /*------------------------------------------------------------------------------------*/
1281 trail
*remove_trail(t
)
1284 /* Pull the little commie out for interrogation: */
1288 for (tl
= t
->tr
; tl
!= NULL
; tl
= tl
->next
)
1290 remove_trailA(t
, (asg_arc
*)tl
->this->this); /* Pull from arc hash table */
1292 remove_trailE(t
, ex
); /* Pull from expn hash table*/
1297 /*------------------------------------------------------------------------------------*/
1299 void replace_trail(tOld
, tNew
)
1302 /* Nuke the little commie: */
1303 expn
*ex
= tOld
->ex
;
1306 for (tl
= tOld
->tr
; tl
!= NULL
; tl
= tl
->next
)
1308 remove_trailA(tOld
, (asg_arc
*)tl
->this->this); /* Pull from arc hash table */
1309 insert_trailA(tNew
, (asg_arc
*)tl
->this->this);
1311 remove_trailE(tOld
, ex
); /* Pull from expn hash table*/
1312 insert_trailE(tNew
, ex
);
1315 free_list(tOld
->used
);
1320 /*------------------------------------------------------------------------------------*/
1322 void add_trail_copy(copy
)
1325 /* add <copy> where ever it belongs */
1326 expn
*ex
= copy
->ex
;
1330 for (tl
= copy
->tr
; tl
!= NULL
; tl
= tl
->next
)
1332 a
= (asg_arc
*)tl
->this->this;
1333 insert_trailA(copy
, a
);
1334 pushnew(copy
->ex
->n
, &a
->nets
);
1336 insert_trailE(copy
, ex
);
1339 /*------------------------------------------------------------------------------------*/
1344 /* This goes through all of the trails listed in ex->queue[] and
1345 deletes them, destroying the table. */
1348 trailist
*trash
, *temp
, *trl
;
1350 for (i
=0; i
<HASH_SIZE
; i
++)
1360 ex
->queue
[i
] = (trailist
*)free_ilist(ex
->queue
[i
]);
1364 /*------------------------------------------------------------------------------------*/
1369 /* This goes through all of the trails listed in ex->queue[] and
1370 recomputes the costs, reordering the table. */
1373 trailist
*temp
, *trash
, *trl
;
1375 ex
->seen
= (tilist
*)free_list(ex
->seen
); /* necessary for yanking dead tiles */
1377 for (i
=0; i
<HASH_SIZE
; i
++)
1381 for (trl
= ex
->queue
[i
]; trl
!= NULL
; trl
= trl
->next
)
1384 if (valid_trail_p(t
) == TRUE
)
1386 t
->cost
= trail_cost(t
);
1387 ordered_ilist_insert(t
, t
->cost
, &temp
);
1388 note_tiles_added(t
, ex
);
1396 trash
= ex
->queue
[i
];
1397 ex
->queue
[i
] = temp
;
1402 /*------- Manage the Hash table in the arc structure: ----------------------------*/
1407 /* Given an expansion, hash your way to it */
1408 unsigned hashval
= (unsigned)(((int)ex
+ ((int)ex
% 5)) % HASH_SIZE
);
1413 /*------------------------------------------------------------------------------------*/
1415 trailist
*lookup_trailA(tr
, a
)
1419 /* This function returns a pointer to the trailist structure where the given
1420 trail <a> should be stored. */
1421 int index
= hashA(tr
->ex
);
1422 if (find_indexed_element(tr
->cost
, a
->trails
[index
]) != NULL
)
1423 return(a
->trails
[index
]);
1427 /*------------------------------------------------------------------------------------*/
1429 int insert_trailA(tr
, a
)
1433 /* This installs <tr> into the hashtable in <a> */
1434 int q
= NULL
, hashval
= hashA(tr
->ex
);
1436 if (valid_trail_p(tr
) == TRUE
)
1438 if ((a
->trails
[ hashval
] != NULL
) &&
1439 (a
->trails
[ hashval
]->this->cost
== tr
->cost
))
1441 /* Deal with the race condition: */
1442 if (break_cost_tie(a
->trails
[hashval
]->this, tr
) == TRUE
) tr
->cost
+= 1;
1443 else a
->trails
[hashval
]->this->cost
+= 1;
1445 q
= ordered_ilist_insert(tr
, tr
->cost
, &a
->trails
[ hashval
]);
1451 /*------------------------------------------------------------------------------------*/
1453 trailist
*remove_trailA(tr
, a
)
1457 /* This removes the given trail from the hash table in <a>. */
1458 int index
= hashA(tr
->ex
);
1459 trail
*q
= (trail
*)irem_item(tr
, &a
->trails
[index
], NULL
);
1460 return(a
->trails
[index
]);
1463 /*------------------------------------------------------------------------------------*/
1465 trail
*best_trailA(a
, ex
)
1469 /* This examines the best trail in the hash table in <a>: that belongs to the
1470 given expansion <ex>. Faked to be non-destructive. */
1472 trailist
*temp
= NULL
;
1473 int index
= hashA(ex
), bestIndex
= 0;
1476 /* Check to make sure that <ex> did not collide with another expansion in the
1478 besTrail
= (trail
*)ipop(&a
->trails
[index
]); /* Get the best trail on this list */
1480 /* If <besTrail> belongs to this expansion <ex>, we're done;
1481 Otherwise, save this entry on <temp> and keep looking */
1482 for (; ((besTrail
->ex
!= ex
) && (a
->trails
[index
] != NULL
));
1483 besTrail
= (trail
*)ipop(&a
->trails
[index
]) )
1484 ipush(besTrail
, &temp
);
1486 /* Cleanup everything that has been pushed onto <temp>:
1487 (This should correct the destructive ipop) */
1488 for(; temp
!= NULL
; temp
= temp
->next
)
1490 /* Push everything back onto <a->trails[index]> */
1491 ordered_ilist_insert(temp
->this, temp
->index
, &a
->trails
[index
]);
1494 /* Achtung! wichtig! return the <besTrail> to the table: */
1495 ordered_ilist_insert(besTrail
, besTrail
->cost
, &a
->trails
[index
]);
1497 return( (besTrail
->ex
== ex
) ? besTrail
: NULL
);
1501 /* This could be written better.... */
1503 /*------------------------------------------------------------------------------------*/
1504 /*------------------------------------------------------------------------------------*/
1506 trail
*any_trailA(a
)
1509 /* This examines the best trail in the hash table in <a>:
1510 Faked to be non-destructive. */
1515 for (i
=0; i
<HASH_SIZE
; i
++)
1517 if (a
->trails
[i
] != NULL
)
1519 nexTrail
= (trail
*)ipop(&a
->trails
[i
]);
1520 ordered_ilist_insert(nexTrail
, nexTrail
->cost
, &a
->trails
[i
]);
1527 /*------------------------------------------------------------------------------------*/
1532 /* This goes through all of the trails listed in a->trails[] and
1533 deletes them, destroying the table. */
1536 trailist
*temp
, *trash
, *trl
;
1538 for (i
=0; i
<HASH_SIZE
; i
++)
1542 for (trl
= a
->trails
[i
]; trl
!= NULL
; trl
= trl
->next
)
1547 a
->trails
[i
] = (trailist
*)free_ilist(a
->trails
[i
]);
1551 /*------------------------------------------------------------------------------------*/
1553 void full_rehashA(a
)
1556 /* This goes through all of the trails listed in a->trails[]
1557 and recomputes the costs, reordering the table. */
1561 trailist
*temp
, *trash
, *trl
;
1563 for (i
= 0; i
< HASH_SIZE
; i
++)
1567 for (trl
= a
->trails
[i
]; trl
!= NULL
; trl
= trl
->next
)
1570 t
->cost
= trail_cost(t
);
1571 ordered_ilist_insert(t
, t
->cost
, &temp
);
1574 trash
= a
->trails
[i
];
1575 a
->trails
[i
] = temp
;
1580 /*------------------------------------------------------------------------------------*/
1586 /* This goes through all of the trails listed in a->trails[] that are associated
1587 with <ex> and recomputes the costs, reordering the table. */
1590 trailist
*temp
, *trash
, *trl
;
1596 for (trl
= a
->trails
[i
]; trl
!= NULL
; trl
= trl
->next
)
1600 t
->cost
= trail_cost(t
);
1601 ordered_ilist_insert(t
, t
->cost
, &temp
);
1604 trash
= a
->trails
[i
];
1605 a
->trails
[i
] = temp
;
1609 /*------------------------------------------------------------------------------------*/
1611 trail
*create_trail(ti
, ex
, p
, dir
)
1614 int p
, dir
; /* array index to the root tile of the next page to be searched. */
1616 /* create a tile structure from scratch : */
1617 trail
*tr
= (trail
*)calloc(1, sizeof(trail
));
1625 tr
->direction
= dir
;
1628 push(ti
, &tr
->tr
); /* Add the tile to the list maintained by the trail */
1629 pushnew(ti
, &ex
->seen
); /* Add the tile to the list of tiles seen */
1630 a
= (asg_arc
*) ti
->this;
1632 /* insert_trailA(tr, a); Don't add the trail to the initial tile just yet */
1633 /* insert_trailE(tr, ex); Don't add the trail to the expansion structure, just yet */
1638 /*------------------------------------------------------------------------------------*/
1639 /*------------------------------------------------------------------------------------*/
1641 trail
*create_subtrail(newTiles
, ex
, p
, dir
)
1644 int p
, dir
; /* array index to the root tile of the next page to be searched. */
1646 /* create a tile structure from scratch : */
1647 trail
*tr
= (trail
*)calloc(1, sizeof(trail
));
1651 tr
->cost
= trail_cost_est(newTiles
, ex
, p
);
1656 tr
->direction
= dir
;
1657 tr
->tr
= (tilist
*)copy_list(newTiles
);
1659 /* Inform the arcs on the list of the new trail being established: */
1660 for (tl
= newTiles
; tl
!= NULL
; tl
= tl
->next
)
1662 a
= (asg_arc
*)tl
->this->this;
1663 insert_trailA(tr
, a
);
1666 /* Clean up the expansion structure: */
1667 insert_trailE(tr
, ex
);
1672 /*------------------------------------------------------------------------------------*/
1674 trail
*copy_trail(t
)
1677 trail
*new = create_trail(NULL
, t
->ex
, t
->page
, t
->direction
);
1679 new->cost
= t
->cost
;
1680 new->tr
= (tilist
*)copy_list(t
->tr
);
1682 new->used
= t
->used
;
1684 /* Don't forget to update the expansion. (insert_trailE()....) */
1685 /* Don't forget to update the tile. (insert_trailA()....) */
1689 /*------------------------------------------------------------------------------------*/
1691 trlist
*remove_all_trails_from_arc(a
)
1694 /* Remove all trails from the given arc. Compile them into a list, and return
1698 trlist
*collectedTrails
= NULL
;
1701 temp
= any_trailA(a
);
1704 push(temp
, &collectedTrails
);
1707 } while (temp
!= NULL
);
1709 a
->nets
= (nlist
*)free_list(a
->nets
);
1712 return(collectedTrails
);
1715 /*------------------------------------------------------------------------------------*/
1717 trail
*add_to_trail(tr
, ti
)
1718 trail
*tr
; /* Trail being added to */
1719 tile
*ti
; /* Tile being added to the list */
1721 /* Add this tile to the existing trail <tr>: Does all of the book keeping for
1722 the arc/tile structures. */
1726 tr
->direction
= toggle_direction(tr
->direction
);
1727 /* Since you're modifyinging the trail, the previous joint may not be valid.*/
1728 tr
->jEx
= NULL
; /* Done so as not to confuse the "valid_trial_p" function ????? */
1732 push(ti
, &tr
->tr
); /* Add the tile to the tile list maintained by the trail */
1733 tr
->cost
= trail_cost(tr
);
1735 /* Add this trail to all of the arcs along the path... */
1736 for (tl
= tr
->tr
; tl
!= NULL
; tl
= tl
->next
)
1738 a
= (asg_arc
*)tl
->this->this;
1739 remove_trailA(tr
, a
); /* The ordering may have changed... */
1740 insert_trailA(tr
, a
);
1743 a
= (asg_arc
*)ti
->this;
1745 if ((debug_level
== 11) && (!strcmp(net_under_study
, tr
->ex
->n
->name
))
1748 a
->local
= tr
->cost
;
1754 /*------------------------------------------------------------------------------------*/
1756 void trim_trails_at(ex
, ti
)
1760 /* find all trails belonging to <ex> in <ti> and clip them at <ti>. This involves
1761 removing all tiles on the trail->tr lists that are in front of <ti>, and
1762 then recosting the whole trail. Later, the set of trails affected needs to be
1763 checked for duplicate trails. */
1764 asg_arc
*a
= (asg_arc
*)ti
->this;
1767 trailist
*trl
, *temp
= NULL
;
1768 trlist
*trll
, *trailSeen
= NULL
, *uniqueTrails
= NULL
;
1770 /* get the trails belonging to <ex> that pass through <a>: */
1771 temp
= (trailist
*)copy_ilist(a
->trails
[hashA(ex
)]);
1773 for (trl
= temp
; trl
!= NULL
; trl
= trl
->next
)
1775 if (trl
->this->ex
== ex
) /* Only look at trails belonging to <ex> */
1778 remove_trailE(t
, ex
); /* Pull from expn hash table*/
1780 /* Remove all tiles from the list up to (but not including) <ti>: */
1781 for (tl
= t
->tr
; ((tl
!= NULL
) && (tl
->this != ti
));
1784 remove_trailA(t
, (asg_arc
*)tl
->this->this ); /* Pull from asg_arc hash table */
1785 pop(&t
->tr
); /* Yank this (extraneous) tile.*/
1788 /* Now remove <ti>: */
1790 { /* Now remove <ti>: */
1791 remove_trailA(t
, (asg_arc
*)tl
->this->this );
1792 pop(&t
->tr
); /* Yank <ti>, then reinsert later... */
1794 /* Now reconstruct the trails, adding the tile back again, and
1795 recomputing it's cost: */
1796 /* NOTE: This will screw up a->trails[...], hence the "copy_ilist" call */
1797 add_to_trail(t
, ti
); /* Does bookeeping (costs, etc.) */
1798 insert_trailE(t
, ex
); /* Add back to expn hash table */
1799 push(t
, &trailSeen
); /* Save for posterity */
1805 /* Look for, and remove duplicate trails: */
1806 for (trll
= trailSeen
; trll
!= NULL
; trll
= trll
->next
)
1809 if (unique_trail(t
, &uniqueTrails
) == FALSE
)
1811 delete_trail(trll
->this);
1814 free_list(trailSeen
);
1817 /*------------------------------------------------------------------------------------*/
1818 /*------------------------------------------------------------------------------------*/
1820 int opposite_side(dir
)
1825 case LEFT
: return(RIGHT
);
1826 case UP
: return(DOWN
);
1827 case RIGHT
:return(LEFT
);
1828 case DOWN
: return(UP
);
1833 /*------------------------------------------------------------------------------------*/
1835 int toggle_direction(lastOrientation
)
1836 int lastOrientation
;
1838 /* This toggles the direction that the expansion set is saught from; That is,
1839 if the last set of expansions came from the routingRoot[HORZ][p] plane, then
1840 the next set should come from the routingRoot[VERT][p] plane & vv. */
1842 if (lastOrientation
== HORZ
) return(VERT
);
1846 /*------------------------------------------------------------------------------------*/
1848 expn
*create_expansion(t
)
1851 /* create an expansion node for this terminal */
1852 expn
*ex
= (expn
*)calloc(1, sizeof(expn
));
1856 ex
->siblings
= NULL
; ex
->connections
= NULL
;
1858 for (i
=0; i
<HASH_SIZE
; i
++) ex
->queue
[i
] = NULL
;
1859 push(ex
, &t
->nt
->expns
); /* Tie the expansion into the net structure */
1860 push(ex
, &ex
->siblings
);
1864 /*-----------------------------------------------------------------------------------*/
1866 int length_to_next_corner(t1
, t2
, orgX
, orgY
, useOrg
, x
, y
)
1868 int orgX
, orgY
, useOrg
;
1871 /* This returns the length in <t1> up to <t2>, correctly handling the
1872 null conditions. It's side effect is to produce the appropriate
1873 coordinates for the point of intersection between <t1> & <t2> */
1875 int q1
= 0, q2
= 0, midpnt
= 0;
1879 if (t2
== NULL
) return (0);
1882 a2
= (asg_arc
*)t2
->this;
1883 *x
= t2
->x_pos
+ (t2
->x_len
/ 2);
1884 *y
= t2
->y_pos
+ (t2
->y_len
/ 2);
1885 if (useOrg
== FALSE
) return(t2
->x_len
/2);
1886 else return( (int)abs(orgX
- (t2
->x_pos
+ t2
->x_len
)) );
1890 a1
= (asg_arc
*)t1
->this;
1894 *x
= t1
->x_pos
+ (t1
->x_len
/ 2);
1895 *y
= t1
->y_pos
+ (t1
->y_len
/ 2);
1896 if (useOrg
== FALSE
) return(t1
->x_len
/2);
1897 else return( (int)abs(orgX
- (t1
->x_pos
+ t1
->x_len
)) );
1901 else /* Given both tiles, determine the length of t2 that is available
1902 after the intersection point of the two tiles. */
1904 a2
= (asg_arc
*)t2
->this;
1905 if ((a1
->page
== VERT
) && (a2
->page
== HORZ
))
1907 find_intersection(t1
->x_pos
, t1
->x_pos
+ t1
->x_len
,
1908 t2
->y_pos
, t2
->y_pos
+ t2
->y_len
, &q1
, &q2
);
1909 midpnt
= (q1
+ q2
) / 2;
1911 *x
= t1
->y_pos
+ (t1
->y_len
/ 2);
1912 return((useOrg
== FALSE
) ? t1
->x_len
/ 2 : (int) abs(orgY
- midpnt
));
1914 else if ((a1
->page
== HORZ
) && (a2
->page
== VERT
))
1916 find_intersection(t2
->y_pos
, t2
->y_pos
+ t2
->y_len
,
1917 t1
->x_pos
, t1
->x_pos
+ t1
->x_len
, &q1
, &q2
);
1918 midpnt
= (q1
+ q2
) / 2;
1920 *y
= t1
->y_pos
+ (t1
->y_len
/ 2);
1921 return((useOrg
== FALSE
) ? t1
->x_len
/ 2 : (int) abs(orgX
- midpnt
));
1923 else /* Adjacent tiles, how odd... */
1925 *x
= t2
->x_pos
+ (t2
->x_len
/ 2);
1926 *y
= t2
->y_pos
+ (t2
->y_len
/ 2);
1927 if(a2
->page
== HORZ
)
1928 return( (useOrg
== FALSE
) ? (t2
->y_len
+ t1
->y_len
) / 2 :
1929 (int)abs (orgY
- *y
));
1930 else return( (useOrg
== FALSE
) ? (t2
->x_len
+ t1
->x_len
) / 2 :
1931 (int) abs(orgX
- *x
));
1936 /*-----------------------------------------------------------------------------------*/
1938 int distance_to_go(ex
, x
, y
, closestEx
)
1943 /* Given the (x, y) position of this particular piece of <ex>, find the minimum
1944 manhattan distance to a legal terminus of <ex>. The set of legal terminii
1945 is the terminals corresponding to the expansions that are part of <ex>->n, but
1946 are not siblings of <ex>. */
1950 int tempX
, tempY
, dist
, minDist
= FALSE
;
1952 for (exl
= (expnlist
*)ex
->n
->expns
; exl
!= NULL
; exl
= exl
->next
)
1954 if (member_p(exl
->this, ex
->siblings
, identity
) == FALSE
)
1957 tempX
= t
->x_pos
+ t
->mod
->x_pos
+ 2 * terminal_spacer(t
, X
);
1958 tempY
= t
->y_pos
+ t
->mod
->y_pos
+ 2 * terminal_spacer(t
, Y
);
1959 dist
= (int)abs(tempX
- x
) + (int)abs(tempY
- y
) +
1960 EXPECTED_CORNERS
* CORNER_COST
;
1961 if ((minDist
== FALSE
) || (dist
<= minDist
))
1964 *closestEx
= exl
->this;
1969 if (minDist
!= FALSE
) return ((int)(minDist
* FORWARD_EST_MULTIPLIER
));
1970 else return(0); /* Problem */
1973 /*-----------------------------------------------------------------------------------*/
1978 /* Estimate the cost to use this trail. */
1980 return(trail_cost_est(tr
->tr
, tr
->ex
, tr
->page
, &a
, &b
, &c
, &d
));
1983 /*-----------------------------------------------------------------------------------*/
1985 int trail_cost_est(tiles
, ex
, page
, trailLength
, trailEst
, tileCount
, trailCong
)
1988 int page
, *trailLength
, *trailEst
, *tileCount
, *trailCong
;
1991 /* Estimate the cost for the given expansion to use this string of tiles. */
1993 int lookaheadEstimate
, length
= 0, cornerCount
= 1;
1994 int congestionCost
= 0;
1995 int tx
, ty
, cornX
, cornY
;
1998 expn
*nearestEx
= NULL
;
2000 tile
*lasTile
= (tiles
!= NULL
) ? tiles
->this : NULL
;
2001 tile
*curTile
= ((lasTile
!= NULL
) && (tiles
->next
!= NULL
)) ?
2002 tiles
->next
->this : NULL
;
2003 tile
*nexTile
= ((curTile
!= NULL
) && (tiles
->next
->next
!= NULL
)) ?
2004 tiles
->next
->next
->this : NULL
;
2007 /* What should be be returning in this case (where something has */
2008 /* gone badly wrong)? */
2009 if (lasTile
== NULL
) {
2010 error("trail_cost_est: passed a NULL tile", "");
2014 /* Handle the first tile on the trail: */
2015 a
= (asg_arc
*)lasTile
->this;
2017 congestionCost
= congestion_cost(a
);
2019 /* Set up the corner point, but ignore the length estimate (no corner to base
2021 length_to_next_corner(lasTile
, curTile
, cornX
, cornY
, FALSE
, &cornX
, &cornY
);
2023 /* If this is a complete trail, that is it connects to the closest expansion
2024 not in <ex>'s expansion group, then measure the distance from (<cornX>,<cornY>)
2025 to <nearestEx>'s terminal. Otherwise, use the <lookaheadEstimate>. */
2027 lookaheadEstimate
= distance_to_go(ex
, cornX
, cornY
, &nearestEx
);
2028 if (nearestEx
!= NULL
)
2030 termTile
= initial_move(nearestEx
, page
);
2031 if (termTile
== lasTile
)
2033 tx
= nearestEx
->t
->mod
->x_pos
+ nearestEx
->t
->x_pos
;
2034 ty
= nearestEx
->t
->mod
->y_pos
+ nearestEx
->t
->y_pos
;
2035 length
+= (int)abs(cornX
- tx
);
2036 length
+= (int)abs(cornY
- ty
);
2038 else length
= lookaheadEstimate
;
2042 /* Set up to evaluate the second tile: */
2045 nexTile
= ((nexTile
!= NULL
) && (tiles
->next
->next
->next
!= NULL
)) ?
2046 tiles
->next
->next
->next
->this : NULL
;
2048 /* There are three or more tiles on the trail: */
2049 for (tl
= (nexTile
!= NULL
) ? tiles
->next
->next
->next
->next
: NULL
;
2051 tl
= (tl
!= NULL
) ? tl
= tl
->next
: NULL
)
2053 a
= (asg_arc
*)lasTile
->this;
2054 congestionCost
+= congestion_cost(a
);
2055 if (curTile
!= NULL
)
2057 length
+= length_to_next_corner(lasTile
, curTile
, cornX
, cornY
,
2058 TRUE
, &cornX
, &cornY
);
2063 length
+= (int)abs(cornX
- (ex
->t
->x_pos
+ ex
->t
->mod
->x_pos
));
2064 length
+= (int)abs(cornY
- (ex
->t
->y_pos
+ ex
->t
->mod
->y_pos
));
2067 /* Set up to evaluate the next tile: */
2070 nexTile
= (tl
!= NULL
) ? tl
->this : NULL
;
2073 *trailLength
= length
;
2074 *trailEst
= lookaheadEstimate
;
2075 *tileCount
= cornerCount
;
2076 *trailCong
= congestionCost
;
2078 return(length
* LENGTH_WEIGHT
+ cornerCount
* CORNER_COST
+ congestionCost
);
2081 /*-------------------------------------------------------------------------------------*/
2083 int break_cost_tie(tr1
, tr2
)
2086 /* return TRUE iff the cost of <tr1> is preferred to that of <tr2>: */
2088 int length1
, length2
, moveCount1
, moveCount2
;
2089 int forwardEst1
, forwardEst2
;
2090 int congestion1
, congestion2
, totalCost1
, totalCost2
;
2092 if (valid_trail_p(tr1
) == FALSE
)
2096 if (valid_trail_p(tr2
) == FALSE
)
2101 totalCost1
= trail_cost_est(tr1
->tr
, tr1
->ex
, tr1
->page
, &length1
,
2102 &forwardEst1
, &moveCount1
, &congestion1
);
2104 totalCost2
= trail_cost_est(tr2
->tr
, tr2
->ex
, tr2
->page
, &length2
,
2105 &forwardEst2
, &moveCount2
, &congestion2
);
2108 if (totalCost1
< totalCost2
) return (TRUE
);
2109 else if (totalCost1
> totalCost2
) return(FALSE
);
2112 if (congestion1
< congestion2
) return(TRUE
);
2113 else if (congestion1
> congestion2
) return(FALSE
);
2116 if (moveCount1
< moveCount2
) return(TRUE
);
2117 else if (moveCount1
> moveCount2
) return(FALSE
);
2120 if (length1
> length2
) return(FALSE
);
2121 else if (length1
< length2
) return(TRUE
);
2124 if (forwardEst1
< forwardEst2
) return(TRUE
);
2125 else if (forwardEst1
> forwardEst2
) return(FALSE
);
2128 if (tr1
->jEx
!= NULL
)return(TRUE
);
2129 else if (tr2
->jEx
!= NULL
) return(FALSE
);
2138 /*------------------------------------------------------------------------------------*/
2140 int lower_cost(t1
, t2
)
2143 /* This compares the cost of <t1> & <t2>. If <t1> is less expensive than <t2>,
2144 TRUE is returned. */
2146 if (t1
->cost
< t2
->cost
) return(TRUE
);
2150 /*------------------------------------------------------------------------------------*/
2152 int set_congestion1(a
)
2155 /* Congestion defaults to corner count. See `congestion_cost' */
2159 /*------------------------------------------------------------------------------------*/
2161 int set_congestion2(a
)
2164 int crossoverCount
= 0, cornerCount
= 0;
2165 tilist
*temp
= NULL
, *tl
;
2169 /* Count the corners in this tile: */
2170 for(nl
= a
->nets
; nl
!= NULL
; nl
= nl
->next
) cornerCount
++;
2172 /* Examine each tile that crosses this tile... */
2173 temp
= collect_tiles(a
->t
, routingRoot
[toggle_direction(a
->page
)][currentPartition
]);
2174 for (tl
= temp
; tl
!= NULL
; tl
= tl
->next
)
2176 /* Count the number of nets that are in the perpendicular tile: */
2177 perpA
= (asg_arc
*)tl
->this->this;
2178 for(nl
= perpA
->nets
; nl
!= NULL
; nl
= nl
-> next
) crossoverCount
++;
2181 a
->congestion
= cornerCount
* crossoverCount
+ cornerCount
;
2182 return (a
->congestion
);
2186 /*------------------------------------------------------------------------------------*/
2188 select_congestion_rule(congestionRule
)
2191 switch(congestionRule
)
2193 case 1 : set_congestion_value
= (int (*)())set_congestion1
; break;
2194 case 2 : set_congestion_value
= (int (*)())set_congestion2
; break;
2195 default: error("select_congestion_rule - bad rule choice ", "");
2200 /*------------------------------------------------------------------------------------*/
2202 int congestion_cost(a
)
2203 asg_arc
*a
; /* asg_arc to be used... */
2205 /* This is an estimate of what it costs to use the given asg_arc. This should be
2206 refined as a real rout becomes a local route... */
2208 /* The cost of congestion = 2x corner count + crossover count + penalty(if any)
2209 (See `set_congestion2 this function to verify this comment) */
2211 float cost
, TracksAvail
, TracksUsed
;
2213 TracksUsed
= (float)list_length(a
->nets
);
2214 TracksAvail
= (a
->page
== VERT
) ? (float)a
->hcap
: (float)a
->vcap
;
2216 cost
= (TracksUsed
/ TracksAvail
) * TRACK_WEIGHT
+ /* Corner-only component */
2217 a
->congestion
/ TracksAvail
; /* Crossover component */
2219 /* Severely penalize overusage: */
2220 if (TracksUsed
>= (int)TracksAvail
-1)
2222 cost
= 5 * cost
+ 40;
2224 return( (int)(cost
) );
2227 /*------------------------------------------------------------------------------------*/
2228 /*------------------------------------------------------------------------------------*/
2230 /*-------------------------------------------------------------------------
2232 * given static costs built into the routing space, route all nets:
2233 *-------------------------------------------------------------------------
2236 /*------------------------------------------------------------------------*/
2238 int on_same_net(exp1
, exp2
)
2241 return (((int)exp1
->n
== (int)exp2
->n
) && ((int)exp1
!= (int)exp2
));
2244 /*------------------------------------------------------------------------*/
2246 int free_to_route_in_p(t
)
2249 /* Returns TRUE if the tile is free for routing.... */
2250 asg_arc
*a
= (t
!= NULL
) ? (asg_arc
*)t
->this : NULL
;
2251 if ((a
!= NULL
) && (a
->mod
== NULL
)) return(TRUE
);
2255 /*------------------------------------------------------------------------------------*/
2256 /*------------------------------------------------------------------------------------*/
2258 nlist
*list_nets_represented(expns
, temp
)
2262 /* Given a list of expansions, create a list of the nets represented */
2264 for (exl
= expns
; exl
!= NULL
; exl
= exl
->next
)
2266 pushnew(exl
->this->n
, temp
);
2271 /*------------------------------------------------------------------------------------*/
2272 /*------------------------------------------------------------------------------------*/
2274 expn
*locate_fellow_expansion(exlist
, ex_already_found
)
2276 expn
*ex_already_found
;
2278 /* Return the expansion from <exl> that is on the same net as <ex_already_found> */
2282 for (exl
= exlist
; exl
!= NULL
; exl
= exl
->next
)
2284 if (on_same_net(ex_already_found
, exl
->this) == TRUE
) return(exl
->this);
2289 /*------------------------------------------------------------------------------------*/
2291 tilist
*collect_tiles(starTile
, Root
)
2292 tile
*starTile
, *Root
;
2294 /* given an area-of-interest (AOI) based on the dimensions of <startTile>, find
2295 the list of tiles from <Root> that are contained. It is assumed that <starTile>
2296 is not in the same tile-space as <Root>, so the x/y values are inverted.*/
2297 tilist
*temp
= NULL
;
2299 if (debug_level
== 5)
2300 fprintf(stderr
, "Collecting tiles from Root tilespace 0x%x\n", Root
);
2302 temp
= area_enumerate(Root
, &temp
, free_to_route_in_p
,
2303 starTile
->y_pos
, starTile
->x_pos
,
2304 starTile
->y_len
, starTile
->x_len
);
2306 /* Added by Tim 2/5/05: If no tiles were found, but the boundary */
2307 /* of Root borders on the space of interest, then expand Root by */
2308 /* one unit and try again. */
2312 if (debug_level == 5)
2313 fprintf(stderr, "temp = NULL in given area\n");
2314 temp = area_enumerate(Root, &temp, free_to_route_in_p,
2315 starTile->y_pos, starTile->x_pos,
2316 starTile->y_len + 1, starTile->x_len + 1);
2317 if (debug_level == 5) {
2319 fprintf(stderr, "temp = 0x%x in expanded area\n", temp);
2321 fprintf(stderr, "temp = NULL in expanded area\n");
2326 /* end of test code. . . ---Tim */
2331 /*------------------------------------------------------------------------------------*/
2333 trlist
*list_trails_using_A(ex
, A
)
2338 trlist
*temp
= NULL
;
2340 for(tl
= A
->trails
[hashA(ex
)]; tl
!= NULL
; tl
= tl
->next
)
2342 if (tl
->this->ex
== ex
) push(tl
->this, &temp
);
2347 /*------------------------------------------------------------------------------------*/
2348 /*------------------------------------------------------------------------------------*/
2350 tilist
*remove_tiles_on_circular_trail(ex
, besTrail
, completeList
)
2351 expn
*ex
; /* Expansion (group) that is being extended */
2352 trail
*besTrail
; /* Trail that got me here... */
2353 tilist
**completeList
; /* What tiles are expansion candidates */
2355 /* This function returns a list without any tiles that would create a circular
2358 /* Need to insure that the 'NewPathDominates' only applys to tiles on the 'wavefront.' */
2365 copy
= (tilist
*)rcopy_list(*completeList
);
2367 for (tl
= copy
; tl
!= NULL
; tl
= tl
->next
)
2370 if (member_p (newTile
, besTrail
->tr
, identity
) == TRUE
) /* No duplicate tiles */
2371 rem_item(newTile
, completeList
);
2375 for (exl
= ex
->siblings
; exl
!= NULL
; exl
= exl
->next
)
2378 if (member_p (newTile
, ex
->seen
, identity
) == TRUE
)
2380 /* Visited this tile before... */
2381 rem_item(newTile
, completeList
);
2383 /* else - <ex> hasn't visited this guy, so keep checking in the group */
2388 return (*completeList
);
2391 /*------------------------------------------------------------------------------------*/
2392 /*------------------------------------------------------------------------------------*/
2394 trail
*flip_trail(t
)
2398 trlist
*trl
, *temp
, *newConnList
= NULL
;
2402 /* create a new trail for t->jEx: The old one gets trashed. */
2403 newTrail
= create_trail(NULL
, t
->jEx
, t
->page
, VERT
);
2404 newTrail
->jEx
= t
->ex
;
2405 newTrail
->tr
= (tilist
*)rcopy_list(t
->tr
);
2406 newTrail
->cost
= trail_cost(newTrail
);
2408 add_trail_copy(newTrail
); /* Add to all asg_arc hash tables */
2409 remove_trailE(newTrail
, newTrail
->ex
); /* Pull from expn hash table */
2411 queue(newTrail
, &ex
->connections
); /* gs Risky Business... */
2412 pull_trail_from_all_arcs(t
); /* Perhaps it should be returned to the expn
2413 hash table, but then it would compete... */
2414 /* Explicity maintain the ->connections lists: */
2415 trl
= ex
->connections
;
2421 rem_item(t
, &ex
->connections
);
2422 newConnList
= ex
->connections
;
2424 for (exl
= ex
->siblings
; exl
!= NULL
; exl
= exl
->next
)
2426 exl
->this->connections
= newConnList
;
2431 my_free(t
); /* BOOM ! */
2435 /*------------------------------------------------------------------------------------*/
2437 adjust_trailset(expnToSet
, expnToFlip
)
2438 expn
*expnToSet
, *expnToFlip
;
2440 trail
*newTrail
= NULL
;
2443 /* Fix the expnToFlip->connections so that <expnToSet> is represented: To be
2444 represented, an expansion must have a single trail that contains the given
2445 expansion in the ->ex field.
2447 This gets interesting, because <expnToSet> is the expansion known to be unique,
2448 ie: desirous of a trail; The routine is designed to set up the trail for
2449 <expnToFlip>, so if <expnToFlip> has already terminated, then some existing
2450 trail needs to be 'flipped,' making it now representative of its ->jEx
2451 expansion; This 'flip' may require other trails to be flipped, as long
2452 as the <expnToSet> winds up with a trail.
2455 /* find the <expnToSet> and do so: */
2456 for (trl
=expnToFlip
->connections
;
2457 ((trl
!= NULL
) && (trl
->this->jEx
!= expnToSet
)); trl
=trl
->next
);
2461 newTrail
= flip_trail(trl
->this);
2463 if ((newTrail
!= NULL
) && (newTrail
->jEx
!= expnToFlip
))
2464 adjust_trailset(newTrail
->jEx
, expnToFlip
);
2468 /*------------------------------------------------------------------------------------*/
2470 void terminate_expansion(ex
, jEx
, jArc
, besTrail
, ActiveExpns
)
2474 expnlist
**ActiveExpns
;
2476 /* Record the termination position (asg_arc) of the expansion, notify the net that
2477 the expn is done, and clip it from the <ActiveExpn> list. */
2478 int q
, xAv
, yAv
, xPos
, yPos
;
2479 int startCost
= besTrail
->cost
;
2484 tilist
*tl
, *completionList
;
2485 expn
*newJex
= NULL
, *whoStopped
= NULL
;
2488 for (exl
= ex
->siblings
; ((exl
!= NULL
) && (whoStopped
== NULL
)); exl
= exl
->next
)
2490 /* Make sure somebody we care about stops */
2491 whoStopped
= (expn
*)rem_item(exl
->this, ActiveExpns
);
2494 if (whoStopped
!= NULL
)
2496 push(whoStopped
, &n
->done
);
2497 if (whoStopped
!= ex
) /* Indirection! */
2499 /* The end object is to arrange that at the end of the termination process,
2500 the global route needs to consist of a set of trails where each trail
2501 represents a unique terminal. */
2503 adjust_trailset(whoStopped
, ex
);
2506 jEx
->siblings
= (expnlist
*)append_list(jEx
->siblings
, ex
->siblings
);
2508 /* Now create the trail that comprises the complete path from <ex> to <jEx>: */
2509 sibTrail
= best_trailA(jArc
, jEx
);
2510 for (tl
= sibTrail
->tr
; ((tl
!= NULL
) && (tl
->this != jArc
->t
)); tl
= tl
->next
);
2511 completionList
= tl
;
2512 for (tl
= completionList
->next
; tl
!= NULL
; tl
= tl
->next
)
2514 add_to_trail(besTrail
, tl
->this);
2517 besTrail
->jEx
= jEx
;
2518 push(besTrail
, &ex
->connections
);
2519 jEx
->connections
= (trlist
*)append_list(jEx
->connections
, ex
->connections
);
2521 if (debug_level
>= 4)
2523 /* print out something useful... */
2524 q
= list_length(ex
->n
->done
);
2525 xAv
= (jArc
->t
->x_pos
+ jArc
->t
->x_len
)/ 2;
2526 yAv
= (jArc
->t
->y_pos
+ jArc
->t
->y_len
)/ 2;
2527 if (jArc
->page
== VERT
)
2530 xAv
= (jArc
->t
->y_pos
+ jArc
->t
->y_len
)/ 2;
2533 if (whoStopped
!= ex
)
2536 "****<%s>\t{%s %s} terminated via <%s>{%s %s} near (%d, %d)%s after %d visits\n",
2537 whoStopped
->n
->name
, whoStopped
->t
->name
, whoStopped
->t
->mod
->name
,
2538 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2539 xAv
, yAv
, (jArc
->page
== VERT
) ? "v" : "h", ex
->eCount
);
2544 "****<%s>\t{%s %s} terminated near (%d, %d)%s after %d visits[%d/%d]\n",
2545 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2546 xAv
, yAv
, (jArc
->page
== VERT
) ? "v" : "h",
2547 ex
->eCount
, startCost
, besTrail
->cost
);
2549 fprintf(stderr
, "****<%s> \t{%s %s} merged with <%s> {%s %s}\n",
2550 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2551 jEx
->n
->name
, jEx
->t
->name
, jEx
->t
->mod
->name
);
2554 if (list_length(n
->done
) + 1 == list_length(n
->expns
))
2556 if (member_p(jEx
, *ActiveExpns
, identity
) == TRUE
)
2558 /* Explicitly terminate <jEx>: */
2559 completionList
= (tilist
*)rcopy_list(sibTrail
->tr
);
2560 firsTile
= completionList
->this;
2561 free_list(completionList
);
2562 sibTrail
= create_trail(firsTile
, jEx
, sibTrail
->page
, VERT
);
2563 insert_trailA(sibTrail
, sibTrail
->tr
->this->this);
2564 sibTrail
->jEx
= jEx
; /* This is a terminated trail, so set ->jEx... */
2570 /* Need to explicitly terminiate the remaining active expansion that
2571 <jEx> belongs to, so first find it... */
2572 exl
= (expnlist
*)member(jEx
, *ActiveExpns
, on_same_net
);
2575 /* Then set up a trail with only the first move on it... */
2578 xPos
= t
->x_pos
+ t
->mod
->x_pos
+ terminal_spacer(t
, X
);
2579 yPos
= t
->y_pos
+ t
->mod
->y_pos
+ terminal_spacer(t
, Y
);
2581 firsTile
= locate_first_tile(t
->side
, xPos
, yPos
, sibTrail
->page
);
2582 sibTrail
= create_trail(firsTile
, newJex
, sibTrail
->page
, VERT
);
2583 sibTrail
->jEx
= newJex
; /* This is a terminated trail, so set ->jEx... */
2584 insert_trailA(sibTrail
, sibTrail
->tr
->this->this);
2587 /* Wrap up the <newJx> as well: */
2588 if (firsTile
== (tile
*)nth(besTrail
->tr
, list_length(besTrail
->tr
)))
2589 sibTrail
->jEx
= besTrail
->ex
;
2590 push(sibTrail
, &jEx
->connections
);
2591 push(newJex
, &n
->done
);
2592 rem_item(newJex
, ActiveExpns
);
2594 if (debug_level
>= 4)
2596 /* print out something useful... */
2597 fprintf(stderr
, "****<%s>\t{%s %s} completes the GR for <%s>.\n",
2598 newJex
->n
->name
, newJex
->t
->name
, newJex
->t
->mod
->name
,
2602 /* Complete the merger of the two expansions: */
2603 for (exl
= jEx
->siblings
; exl
!= NULL
; exl
= exl
->next
)
2605 exl
->this->connections
= jEx
->connections
;
2606 exl
->this->siblings
= jEx
->siblings
;
2607 /* The merger changes the "distance_to_go" measure, so recalculate the
2609 rehashE(exl
->this); /* if (newJex == NULL) rehashE(exl->this); */
2614 /*------------------------------------------------------------------------------------*/
2616 int meets_termination_conditions_p(tr
, parentEx
, besTrail
)
2617 trail
*tr
; /* Trail being checked */
2618 expn
*parentEx
; /* Expansion that is being checked for termination */
2619 trail
*besTrail
; /* Best trail so far in the given asg_arc */
2621 if ((tr
->ex
->n
== parentEx
->n
) && /* IF it belongs to the same net */
2623 (member_p(tr
->ex
, parentEx
->siblings
,
2624 identity
) == FALSE
) && /* AND is not part of <parent>'s
2627 ((besTrail
== NULL
) || /* AND is the best trail so far */
2628 (tr
->cost
< besTrail
->cost
) ||
2629 ((besTrail
->jEx
!= NULL
) && (tr
->cost
== besTrail
->cost
))))
2639 /*------------------------------------------------------------------------------------*/
2641 int check_for_AND_terminate_expn(t
, expnsStillActive
)
2643 expnlist
**expnsStillActive
;
2645 /* This seasg_arches through the list of trails that have been hashed into the
2646 proposed jointArc <a>. Within this list of trails, each is checked to see
2647 if it completes a subnet of the <parent> expansion.
2649 IF it so happens that a subnet that is a <besTrail> is discovered (and can
2650 be legally terminated), it is - <expnsStillActive> is decremented, and TRUE
2654 expn
*parentEx
= t
->ex
;
2655 asg_arc
*a
= (asg_arc
*)t
->tr
->this->this; /* Proposed joint arc for <parent> */
2656 trail
*besTrail
= NULL
, *temp
;
2661 for (i
=0; i
<HASH_SIZE
; i
++)
2663 for (trll
= a
->trails
[i
]; trll
!= NULL
; trll
= trll
->next
)
2665 /* the arc lists all trails that cross it. Find all that are on the same
2666 net, but not the same expansion. If any are found, then this expansion
2667 may terminate. Do it.*/
2671 if (meets_termination_conditions_p(temp
, parentEx
, besTrail
) == TRUE
)
2677 if (besTrail
!= NULL
)
2679 terminate_expansion(parentEx
, besTrail
->ex
, a
, t
, expnsStillActive
);
2685 /*------------------------------------------------------------------------------------*/
2687 expnlist
*check_for_termination(t
)
2690 /* This searches through the list of trails that have been hashed into the
2691 proposed jointArc <a>. Within this list of trails, each is checked to see
2692 if it completes a subnet of the <parent> expansion.
2694 IF it so happens that a subnet that is a <besTrail> is discovered (and can
2695 be legally terminated), the pointer the expansion that caused the best terminus
2698 NOTE: There may be more than one of these.
2704 error("check_for_termination: trail is NULL", "");
2707 else if (t
->tr
== NULL
) {
2708 error("check_for_termination: trail component tr is NULL", "");
2712 a
= (asg_arc
*) t
->tr
->this->this; /* Proposed joint arc for <parent> */
2714 expn
*parent
= t
->ex
;
2715 expnlist
*terminationCandidateList
= NULL
;
2716 trail
*temp
, *besTrail
= NULL
;
2721 for (i
=0; i
<HASH_SIZE
; i
++)
2723 for (trll
= a
->trails
[i
]; trll
!= NULL
; trll
= trll
->next
)
2725 /* the asg_arc lists all trails that cross it. Find all that are on the same
2726 net, but not the same expansion. If any are found, then this expansion
2731 if ((temp
!= besTrail
) &&
2732 (meets_termination_conditions_p(temp
, parent
, besTrail
) == TRUE
))
2735 pushnew(temp
->ex
, &terminationCandidateList
);
2739 if (terminationCandidateList
!= NULL
)
2741 return(terminationCandidateList
);
2746 /*------------------------------------------------------------------------------------*/
2748 trail
*examine_best_trail_in_expn_group(ex
)
2750 { /* Generalized form of "examine_best_trailE" */
2752 trail
*t
= NULL
, *tempTrail
;
2754 /* Get the cell to move from-- This is the best trail for the given expansion: */
2755 for (exl
= ex
->siblings
; exl
!= NULL
; exl
= exl
->next
)
2757 /* Check <ex> and all of <ex>'s siblings for the best trail... */
2758 tempTrail
= examine_best_trailE(exl
->this);
2760 ((tempTrail
!= NULL
) && (tempTrail
->cost
<= t
->cost
))) t
= tempTrail
;
2765 /*------------------------------------------------------------------------------------*/
2767 trail
*extract_best_trail_in_expn_group(ex
)
2769 { /* Generalized form of "best_trailE" */
2771 t
= examine_best_trail_in_expn_group(ex
);
2772 remove_trailE(t
, t
->ex
);
2776 /*------------------------------------------------------------------------------------*/
2778 trail
*restart_expansion(ex
)
2779 expn
*ex
; /* expansion being restarted */
2781 /* Delete all discovered trails for this expansion, and start over. */
2783 static expn
*lastEx
;
2785 trail
*t
, *make_startup_trail();
2788 if (lastEx
== ex
) return(NULL
);
2792 ex
->connections
= NULL
; /* Should be NULL already */
2793 ex
->seen
= (tilist
*) free_list(ex
->seen
);
2795 t
= make_startup_trail(ex
, initial_move(ex
, 0), 0);
2796 if (t
->tr
== NULL
) {
2797 error("restart_expansion: trail has NULL component", "");
2798 return NULL
; /* Something has gone wrong. . . */
2800 a
= (asg_arc
*)t
->tr
->this->this;
2801 insert_trailA(t
, a
);
2802 insert_trailE(t
, ex
); /* Will be the only trail in the expansion group */
2807 /*------------------------------------------------------------------------------------*/
2809 int make_next_best_move(ex
, trailsCompleted
)
2811 trlist
**trailsCompleted
;
2813 /* make the next best move for this expansion. This involves removing the best trail
2814 * from the priority queue, expanding from the end of that trail, */
2815 tile
*lasTile
, *starTile
, *nexTile
;
2817 int done_count
, undone_count
, expnsToGo
;
2818 tilist
*tl
, *tileSet
= NULL
;
2819 trail
*tempTrail
, *t
= NULL
, *trailToUse
;
2820 trlist
*activeTrails
= NULL
;
2821 expn
*nextEx
, *tempEx
;
2822 expnlist
*possibleTerminations
= NULL
, *secondaryTerminations
, *exl
;
2825 /* Get the cell to move from-- This is the best trail for the given expansion: */
2826 t
= examine_best_trail_in_expn_group(ex
);
2829 ((ex
->connections
== NULL
) ||
2830 (list_length(ex
->n
->expns
) - list_length(ex
->n
->done
) < 2)))
2832 t
= restart_expansion(ex
);
2835 fprintf(stderr
, "ERROR: <%s> \t{%s %s} CANCELLED - no more paths!!! \n",
2836 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
);
2842 fprintf(stderr
, "WARNING: <%s> \t{%s %s} LOST - being restarted!!! \n",
2843 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
);
2844 /* Treat this as an error condition and abort */
2845 /* (previously, routine continued, but is in infinite loop at this point) */
2853 t
= extract_best_trail_in_expn_group(ex
);
2856 starTile
= t
->tr
->this;
2857 lasTile
= (t
->tr
->next
!= NULL
) ? t
->tr
->next
->this : t
->tr
->this;
2858 a
= (asg_arc
*)starTile
->this;
2860 /* Check to insure that this trail is not already 'Completed' : */
2861 possibleTerminations
= check_for_termination(t
);
2863 if (possibleTerminations
== NULL
)
2865 /* Continue expanding */
2866 if (debug_level
== 5)
2867 fprintf(stderr
, "**<%s> \t{%s %s} visiting (%d, %d)%s [%d]\n",
2868 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2869 (a
->page
== HORZ
) ? lasTile
->y_pos
+ lasTile
->y_len
/2 :
2870 starTile
->y_pos
+ starTile
->y_len
/2,
2871 (a
->page
== HORZ
) ? starTile
->y_pos
+ starTile
->y_len
/2 :
2872 lasTile
->y_pos
+ lasTile
->y_len
/2,
2873 (a
->page
== VERT
) ? "v" : "h",
2876 /* Collect the set of tiles that can be moved into: */
2877 tileSet
= collect_tiles(starTile
, routingRoot
[t
->direction
][t
->page
]);
2878 tileSet
= remove_tiles_on_circular_trail(ex
, t
, &tileSet
);
2880 /* Take these tiles, and build them into trail structures that can be tracked
2881 through the system... Create a new trail for every tile on the list. The
2882 old trail has the first element of <tileSet> added to it explicitly; All
2883 of the other elements have copies of <t> made, and added to. */
2884 if (tileSet
!= NULL
)
2886 for (tl
= tileSet
->next
; tl
!= NULL
; tl
= tl
->next
)
2888 tempTrail
= copy_trail(t
);
2889 add_to_trail (tempTrail
, tl
->this); /* !Does bookeeping for tile str.!*/
2890 insert_trailE(tempTrail
, ex
); /* Add to expn hash table */
2891 push(tempTrail
, &activeTrails
);
2893 a
= (asg_arc
*)tl
->this->this;
2894 if (debug_level
== 5)
2895 fprintf(stderr
, "<%s> \t{%s %s} expanding to (%d, %d)%s [%d] trail==%x\n",
2896 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2897 (a
->page
== HORZ
) ? starTile
->y_pos
+ starTile
->y_len
/2 :
2898 tl
->this->y_pos
+ tl
->this->y_len
/2,
2899 (a
->page
== HORZ
) ? tl
->this->y_pos
+ tl
->this->y_len
/2 :
2900 starTile
->y_pos
+ starTile
->y_len
/2,
2901 (a
->page
== VERT
) ? "v" : "h",
2902 tempTrail
->cost
, (int)tempTrail
);
2905 for (tl
= t
->tr
; tl
!= NULL
; tl
= tl
->next
)
2907 remove_trailA(t
, (asg_arc
*)tl
->this->this ); /* Pull from arc hash table */
2909 add_to_trail(t
, tileSet
->this); /* Do bookeeping for tile str. */
2910 insert_trailE(t
, ex
); /* Add to expn hash table */
2911 push(t
, &activeTrails
);
2913 a
= (asg_arc
*)tileSet
->this->this;
2914 if (debug_level
== 5)
2915 fprintf(stderr
, "<%s> \t{%s %s} expanding to (%d, %d)%s [%d] trail==%x\n",
2916 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2917 (a
->page
== HORZ
) ? starTile
->y_pos
+ starTile
->y_len
/2 :
2918 tileSet
->this->y_pos
+ tileSet
->this->y_len
/2,
2919 (a
->page
== HORZ
) ? tileSet
->this->y_pos
+ tileSet
->this->y_len
/2 :
2920 starTile
->y_pos
+ starTile
->y_len
/2,
2921 (a
->page
== VERT
) ? "v" : "h",
2926 else /* Got a problem.... */
2928 /* Let the expansion spin; This is an infinite loop, which can only be
2929 terminated by having another expansion terminate. */
2930 /* However, this permision should only occur iff the current expansion
2931 <ex> is NOT part of a terminated series (ie: his ->siblings field is
2932 of length 2 or more & this trail has a valid ->jEx field). */
2933 if ((list_length(*trailsCompleted
) > 1) && /* Not a pathological case */
2934 (t
->jEx
!= NULL
) && /* This trail has completed */
2935 (list_length(ex
->siblings
) >= 2) && /* somewhere AND */
2936 (list_length(ex
->n
->expns
) - /* There is some other expn */
2937 list_length(ex
->n
->done
) >= 2)) /* waiting to complete... */
2939 insert_trailE(t
, t
->ex
); /* Add it back to the hash table so
2940 others can find it... */
2941 t
->ex
->eCount
= FALSE
; /* Mark it */
2942 if (debug_level
== 4)
2944 fprintf(stderr
, "<%s> \t{%s %s} spinning on trail %x.\n",
2945 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
, t
);
2947 /* This needs a clause to catch the completley pathological case. */
2950 /* Since you couldn't expand this trail any more, simply delete it: */
2956 if ((debug_level
== 1) &&
2957 (net_name_located_p(net_under_study
, ex
->n
) == TRUE
))
2964 else /* There is at least one possbile termination */
2966 insert_trailE(t
, t
->ex
); /* Add it back to the hash table so others
2969 for (exl
= possibleTerminations
; exl
!= NULL
; exl
= exl
->next
)
2970 /* exl = possibleTerminations;
2975 if (debug_level
== 5)
2977 fprintf(stderr
, "**<%s> \t{%s %s} may terminate w/ {%s %s} in (%d, %d)%s [%d]\n",
2978 ex
->n
->name
, ex
->t
->name
, ex
->t
->mod
->name
,
2979 nextEx
->t
->name
, nextEx
->t
->mod
->name
,
2980 (a
->page
== HORZ
) ? lasTile
->y_pos
+ lasTile
->y_len
/2 :
2981 starTile
->y_pos
+ starTile
->y_len
/2,
2982 (a
->page
== HORZ
) ? starTile
->y_pos
+ starTile
->y_len
/2 :
2983 lasTile
->y_pos
+ lasTile
->y_len
/2,
2984 (a
->page
== VERT
) ? "v" : "h",
2988 /* Now check to see if this trail is better than the trails in <nextEx>;
2989 If it is, then go ahead and terminate it; Otherwise, leave it in
2990 the hash table (to be found again, and the whole process to repeat)
2991 until either t->cost < min-cost {all trails in <nextEx>} OR <ex>
2992 is terminated by another expansion. */
2994 tempTrail
= examine_best_trail_in_expn_group(nextEx
);
2995 if ((tempTrail
== NULL
) || (tempTrail
->ex
->eCount
== FALSE
) ||
2996 (t
->cost
<= tempTrail
->cost
))
2997 pushnew(t
, trailsCompleted
);
3000 secondaryTerminations
= check_for_termination(tempTrail
);
3001 if (member_p(t
->ex
, secondaryTerminations
, identity
) == TRUE
)
3003 if (t
->cost
< tempTrail
->cost
) push(t
, trailsCompleted
);
3004 else push(tempTrail
, trailsCompleted
);
3006 free_list(secondaryTerminations
);
3009 free_list(possibleTerminations
); /* Collect Garbage */
3017 /*------------------------------------------------------------------------------------*/
3018 /*------------------------------------------------------------------------------------*/
3020 int unique_trail(t
, uniqueTraiList
)
3022 trlist
**uniqueTraiList
;
3024 /* Return true, and add <t> to <uniqueTraiList> iff <t> is unique from all other
3025 trails in <uniqueTraiList>. Otherwise, return FALSE. */
3029 int mayBeDuplicate
= FALSE
;
3031 for(trl
= *uniqueTraiList
; trl
!= NULL
; trl
= trl
->next
)
3033 for(tl
= trl
->this->tr
; tl
!= NULL
; tl
= tl
->next
)
3035 for(tll
= t
->tr
; tll
!= NULL
; tll
= tll
->next
)
3037 if (tll
->this != tl
->this)
3039 push(t
, uniqueTraiList
);
3040 tl
= tll
= NULL
; /* Break */
3042 else mayBeDuplicate
= TRUE
;
3045 if (mayBeDuplicate
== TRUE
) return(FALSE
);
3050 /*-------------------------------------------------------------------------------------*/
3052 int terminal_spacer(t
, axis
)
3056 /* This returns the margin along the given axis that should be added to the
3057 given terminal. Typically 1 or -1. */
3062 if (t
->side
== RIGHT
) margin
= TERM_MARGIN
;
3063 else if (t
->side
== LEFT
) margin
= -TERM_MARGIN
;
3067 if (t
->side
== UP
) margin
= TERM_MARGIN
;
3068 else if (t
->side
== DOWN
) margin
= -TERM_MARGIN
;
3073 /*------------------------------------------------------------------------------------*/
3075 tile
*locate_first_tile(side
, x_pos
, y_pos
, page
)
3076 int side
, x_pos
, y_pos
, page
;
3080 if ((side
== LEFT
) || (side
== RIGHT
)) /* IN or OUT terminals... */
3082 hTile
= locate(routingRoot
[HORZ
][page
], x_pos
, y_pos
);
3083 if (!hTile
|| (hTile
->y_pos
+ hTile
->y_len
== y_pos
)) {
3084 hTile
= locate(hTile
, x_pos
, y_pos
+ 1);
3087 /* Maybe type inout without being on the left or right? */
3088 hTile
= locate(routingRoot
[VERT
][page
], y_pos
, x_pos
);
3091 else /* For inout terminals.... */
3093 hTile
= locate(routingRoot
[VERT
][page
], y_pos
, x_pos
);
3099 /*------------------------------------------------------------------------------------*/
3101 tile
*initial_move(ex
, page
)
3105 /* Return the horizontal Tile in which to start a move */
3106 /* This takes an expansion and moves it into the htile that the terminal
3107 must be routed through. NOTE: All first moves occur in the hspace. This
3108 may be incorrect; If a terminal starts on the UP/DOWN side, perhaps they
3109 should start in the vspace. */
3113 int x_pos
= t
->x_pos
+ m
->x_pos
+ terminal_spacer(t
, X
);
3114 int y_pos
= t
->y_pos
+ m
->y_pos
+ terminal_spacer(t
, Y
);
3115 tile
*hTile
= locate_first_tile(t
->side
, x_pos
, y_pos
, page
);
3120 /*------------------------------------------------------------------------------------*/
3122 trail
*make_startup_trail(ex
, starTile
, page
)
3129 if ((ex
->t
->side
== LEFT
) || (ex
->t
->side
== RIGHT
)) /* IN or OUT terminals... */
3131 tr
= create_trail(starTile
, ex
, page
, VERT
);
3133 else /* For INOUT terminals.... */
3135 tr
= create_trail(starTile
, ex
, page
, HORZ
);
3138 tr
->cost
= trail_cost(tr
);
3143 /*------------------------------------------------------------------------------------*/
3145 trail
*old_make_first_move(ex
, page
)
3149 /* This takes an expansion and moves it into the htile that the terminal
3150 must be routed through. NOTE: All first moves occur in the hspace. This
3151 may be incorrect; If a terminal starts on the UP/DOWN side, perhaps they
3152 should start in the vspace. */
3156 int x_pos
= t
->x_pos
+ m
->x_pos
+ terminal_spacer(t
, X
);
3157 int y_pos
= t
->y_pos
+ m
->y_pos
+ terminal_spacer(t
, Y
);
3158 tile
*hTile
= locate_first_tile(t
->side
, x_pos
, y_pos
, page
);
3161 if ((t
->side
== LEFT
) || (t
->side
== RIGHT
)) /* IN or OUT terminals... */
3163 tr
= create_trail(hTile
, ex
, page
, VERT
);
3165 else /* For inout terminals.... */
3167 tr
= create_trail(hTile
, ex
, page
, HORZ
);
3170 tr
->cost
= trail_cost(tr
);
3175 /*------------------------------------------------------------------------------------*/
3177 expn
*make_first_moves(ActiveExpns
, AllExpns
, p
)
3178 expnlist
**ActiveExpns
; /* source list for active expansions */
3180 int p
; /* partition being worked on */
3188 /* make the first (required) moves for this set of expansions. */
3189 for (exl
= AllExpns
; exl
!= NULL
; exl
= exl
->next
)
3192 ex
->eCount
+= 1; /* Keep Statistics */
3194 t
= make_startup_trail(ex
, initial_move(ex
, p
), p
);
3195 if (t
->tr
== NULL
) {
3196 error("make_first_moves: trail has NULL component", "");
3197 break; /* Something has gone wrong. . . */
3199 a
= (asg_arc
*)t
->tr
->this->this;
3200 insert_trailA(t
, a
);
3203 if (check_for_AND_terminate_expn(t
, ActiveExpns
) == FALSE
)
3205 insert_trailE(t
, ex
);
3208 if ((debug_level
== 1) &&
3209 (net_name_located_p(net_under_study
, ex
->n
) == TRUE
))
3216 /*------------------------------------------------------------------------------------*/
3218 int trail_cost_order(t1
, t2
)
3221 if (t1
== NULL
) return(FALSE
); /* Not good... */
3222 else if (t2
== NULL
) return(TRUE
); /* Not good... */
3223 else if (t1
->cost
<= t2
->cost
) return(TRUE
);
3227 /*------------------------------------------------------------------------------------*/
3229 int in_trailCost_order(e1
, e2
)
3232 trail
*t1
= examine_best_trail_in_expn_group(e1
);
3233 trail
*t2
= examine_best_trail_in_expn_group(e2
);
3235 if (t1
== NULL
) return(FALSE
); /* Not good... */
3236 else if (t2
== NULL
) return(TRUE
); /* Not good... */
3237 else if (t1
->cost
<= t2
->cost
) return(TRUE
);
3241 /*------------------------------------------------------------------------------------*/
3243 int move_expns(expnsToMove
)
3244 expnlist
**expnsToMove
;
3246 /* this function performs a breadth-first Lee-type weighted, multi-source maze
3247 route to arrange the given <nets> within the routing space. <expns> is a
3248 list of source terminals/expansions, such that there is one terminal/expansion
3251 /* As this may well be operating on a partial schematic, only those terminals
3252 listed are acted upon; In this same way, expansion information is maintained,
3253 even as sections of the route are completed, and ranges are placed in the
3254 appropriate arcs(tiles). */
3257 expnlist
*exl
, *etemp
, *terminationCandidates
;
3259 trlist
*trl
, *ttemp
, *trailsCompleted
= NULL
;
3261 while(*expnsToMove
!= NULL
)
3263 /* have all expansions (there is one for every terminal) made the least-expensive
3264 (upward?) expansions:
3265 - Do not enter an area to which this terminal has already expanded. */
3267 /* Move all active expansion groups one step... */
3268 for (exl
= (expnlist
*)sort_list(*expnsToMove
, in_trailCost_order
);
3269 exl
!= NULL
; exl
= exl
->next
)
3271 if (make_next_best_move(exl
->this, &trailsCompleted
) < 0) {
3272 error("move_expns: make_next_best_move returned error condition");
3277 /* check all expansion groups for terminations: */
3278 trl
= (trlist
*)sort_list(trailsCompleted
, trail_cost_order
);
3285 terminationCandidates
= check_for_termination(t
);
3286 exl
= terminationCandidates
;
3290 jEx
= exl
->this;/* Still to be terminated? */
3291 if (jEx
!= NULL
)/* Other terminations may have superceded this one... */
3293 temp
= examine_best_trail_in_expn_group(t
->ex
);
3296 remove_trailE(t
, t
->ex
);
3297 terminate_expansion(t
->ex
, jEx
, t
->tr
->this->this, t
, expnsToMove
);
3299 free_list(terminationCandidates
);
3300 /* Break added by Tim (9/24/03); */
3301 /* otherwise, exl is invalid on next loop */
3306 jEx
= jEx
; /* NOP */
3310 trailsCompleted
= (trlist
*)free_list(trailsCompleted
); /* Collect garbage */
3317 /*------------------------------------------------------------------------------------*/
3319 int first_cut(expns
, part
)
3323 expnlist
*exl
, *ExpCopy
= (expnlist
*)rcopy_list(expns
);
3324 /* <ExpCopy> is the list of expansions that have not terminated. Its length
3325 corresponds to <expCount>. */
3328 /* Make the first set of expansions, checking them to see if there are any
3329 expansions that are immediately terminated: */
3330 make_first_moves(&ExpCopy
, expns
, part
);
3332 return move_expns(&ExpCopy
);
3335 /*------------------------------------------------------------------------------------*/
3336 /*------------------------------------------------------------------------------------*/
3338 asg_arc
*Nth(modTlist
, n
)
3342 tile
*t
= (tile
*)nth(modTlist
, n
);
3343 return((asg_arc
*)t
->this);
3346 /*------------------------------------------------------------------------------------*/
3351 /* returns TRUE if the given asg_arc is filled */
3352 if (a
->mod
== NULL
) return(FALSE
);
3356 /*------------------------------------------------------------------------------------*/
3358 void set_arc_costs(netsToSet
)
3361 /* This walks through the connection trails for each of the given nets,
3362 painting the tiles traversed with an estimate of their usage(congestion). */
3371 for (nl
= netsToSet
; nl
!=NULL
; nl
= nl
->next
)
3373 ex
= (expn
*)nl
->this->done
->this;
3374 for (trl
= ex
->connections
; trl
!= NULL
; trl
= trl
->next
)
3377 for (tl
= bt
->tr
; tl
!= NULL
; tl
= tl
->next
)
3379 /* Paint each arc with the usage - assume VERT tiles essentially have
3380 only the vertical tracks employed, and HORZ tiles the horizontal
3382 a
=(asg_arc
*)tl
->this->this;
3383 pushnew(nl
->this, &a
->nets
); /* Mark the global route used */
3384 (*set_congestion_value
)(a
);
3390 /*------------------------------------------------------------------------------------*/
3392 return_best_trails_to_arcs(n
,expnsToReroute
, part
)
3394 expnlist
*expnsToReroute
;
3395 int part
; /* Not used */
3397 /* This returns the best trails contained in <n> to the appropriate hash tables. */
3399 expnlist
*exl
, *sibList
;
3403 tilist
*tl
, *affectedTiles
= NULL
;
3405 if (n
->done
== NULL
) return; /* Nothing to return */
3407 ex
= (expn
*)n
->done
->this;
3409 /* return the 'best routes' to the expansion hash tables for the next go-round
3410 It is important to create an extra trail for to insure that all of the known
3411 (especially the implicitly-known) complete trails are available to be found. */
3412 for (trl
= ex
->connections
; trl
!= NULL
; trl
= trl
->next
)
3414 insert_trailE(trl
->this, trl
->this->ex
);
3415 for (tl
= trl
->this->tr
; tl
!= NULL
; tl
= tl
->next
)
3417 ar
= (asg_arc
*)tl
->this->this;
3418 rem_item(n
, &ar
->nets
);
3421 ex
->connections
= (trlist
*)free_list(ex
->connections
);
3423 /* Now reset all of the information in the expansion structures: */
3424 sibList
= ex
->siblings
;
3426 for (exl
= sibList
; exl
!= NULL
; exl
= exl
->next
)
3430 /* Clean up the parent net: */
3431 rem_item(ex
, &n
->done
);
3432 ex
->siblings
= NULL
;
3433 push(ex
, &ex
->siblings
);
3434 ex
->connections
= NULL
;
3435 ex
->eCount
= 0; /* Start the visitation count over */
3441 /* Reorder the hash tables for those arcs that have had things added back to them */
3442 for (tl
= ex
->seen
; tl
!= NULL
; tl
= tl
->next
)
3444 rehashA(tl
->this->this, ex
);
3448 /*------------------------------------------------------------------------------------*/
3450 reset_all_trail_costs(nets
, part
)
3454 /* This resets the trail costs for the entire seasg_arch space. */
3460 tilist
*tl
, *affectedTiles
= NULL
;
3462 /* Reorder the hash tables for all arcs in the routing space */
3464 affectedTiles
= allspace(routingRoot
[VERT
][part
], &affectedTiles
);
3465 for (tl
= affectedTiles
; tl
!= NULL
; tl
= tl
->next
)
3467 ar
= (asg_arc
*)tl
->this->this;
3470 affectedTiles
= (tilist
*)free_list(affectedTiles
);
3472 affectedTiles
= allspace(routingRoot
[HORZ
][part
], &affectedTiles
);
3473 for (tl
= affectedTiles
; tl
!= NULL
; tl
= tl
->next
)
3475 full_rehashA(tl
->this->this);
3477 affectedTiles
= (tilist
*)free_list(affectedTiles
);
3479 for (nl
= nets
; nl
!= NULL
; nl
= nl
->next
)
3481 ex
= (expn
*)nl
->this->done
->this;
3484 /* Rehash the expansion tables and the current (active) trail: */
3485 for (exl
= ex
->siblings
; exl
!= NULL
; exl
= exl
->next
)
3490 /* Recost the trails in the net structure: (probably pointless, as these get
3491 added back to the arcs again later...) */
3492 for (trl
= ex
->connections
; trl
!= NULL
; trl
= trl
->next
)
3494 trl
->this->cost
= trail_cost(trl
->this);
3499 /*------------------------------------------------------------------------------------*/
3501 improve_route(n
, part
)
3505 /* This function takes the most best arcs on the net, returns them to the hash table
3506 (rips them up) and tries again after rehashing the tables. This causes a
3507 rehash on all of the expansion tables for this net, and for all of the tiles
3508 traversed by the trails returned to an `unused' status (see `return_best_trails_
3511 expnlist
*expns_to_reroute
= (expnlist
*)rcopy_list(n
->done
);
3513 /* List the expansion nodes from these affected nets: (Controls the re-route) */
3514 /* Then rip out the nets from the page :*/
3516 /* Only expansions belonging to <n> will be re-routed (and hopefully improved...)*/
3520 return_best_trails_to_arcs(n
, expns_to_reroute
, part
);
3522 /* Reroute the expansions: (This means, continue where the routing left off...*/
3523 move_expns(&expns_to_reroute
);
3524 free_list(expns_to_reroute
);
3527 /*------------------------------------------------------------------------------------*/
3529 allow_for_further_routing(activeNets
, part
)
3531 int part
; /* Not Used */
3533 /* Trash all of the existing trails, then return all of the completed routes
3534 belonging to <activeNets>. Arrange the data structures so that
3535 the insertion and routing algorithms can be rerun */
3540 for (nl
= activeNets
; nl
!= NULL
; nl
= nl
->next
)
3542 /* Blow away the extraneous Global Routing stuff... */
3543 for (exl
= (expnlist
*)nl
->this->expns
; exl
!= NULL
; exl
= exl
->next
)
3545 kill_hashE(exl
->this); /* Blam! */
3548 /* Blow away the Local Routing stuff... */
3549 if (nl
->this->done
!= NULL
)
3551 delete_all_corners(nl
->this->route
);
3552 nl
->this->route
= NULL
;
3555 return_best_trails_to_arcs(nl
->this, part
);
3556 nl
->this->rflag
= NULL
;
3558 if (debug_level
> 2)
3560 fprintf(stderr
,"...net<%s> reset", nl
->this->name
);
3563 if (debug_level
> 2)
3565 fprintf(stderr
,"...done\n");
3569 /*------------------------------------------------------------------------------------*/
3570 /*------------------------------------------------------------------------------------*/
3575 /* This fuction determines if the given net has no terminals (Dummy Net) */
3576 if (n
->terms
== NULL
) return(TRUE
);
3580 /*------------------------------------------------------------------------------------*/
3582 int been_rerouted(n
)
3585 /* This fuction determines if the given net has been rerouted. */
3586 return((n
->rflag
== RIPPED
));
3589 /*------------------------------------------------------------------------------------*/
3591 asg_arc
*worst_arc_on_net(n
)
3594 /* This returns the most congested arc on the current route path of the given net */
3597 asg_arc
*a
, *worstArc
= NULL
;
3598 int congestionLevel
= 0;
3603 ex
= (expn
*)n
->expns
->this;
3604 for (trl
= ex
->connections
; trl
!= NULL
; trl
= trl
->next
)
3606 /* Pick the best trail, so as to trace along it: */
3607 besTrail
= trl
->this;
3609 /* Walk back along the trail, looking for the most congested arc: */
3610 for (tl
= besTrail
->tr
; tl
!= NULL
; tl
= tl
->next
)
3612 a
= (asg_arc
*)tl
->this->this;
3613 if (congestion_cost(a
) >= congestionLevel
)
3615 congestionLevel
= congestion_cost(a
);
3623 /*------------------------------------------------------------------------------------*/
3625 nlist
*non_ripped_up_nets(nl
)
3628 /* return a list of non-ripped-up nets. (Unsorted) */
3629 nlist
*nll
= (nlist
*)copy_list(nl
);
3630 return((nlist
*)delete_if(&nll
, been_rerouted
));
3633 /*------------------------------------------------------------------------------------*/
3634 /*------------------------------------------------------------------------------------*/
3636 void ps_print_arc(f
, t
)
3640 /* This function prints the contents of the given arc in PostScript
3641 format to file <F>. */
3642 asg_arc
*a
= (arc
*)t
->this;
3643 int x1
, x2
, y1
, y2
, count
= 0;
3648 float gray_level
= 1.0 - (float)list_length(a
->nets
) /
3649 (2.5 * (float)list_length(nets
));
3658 /* Fill in the area with gray, shaded to show the number of nets contained */
3659 fprintf(f
, "newpath %d %d moveto %d %d lineto ", x1
, y1
, x2
, y1
);
3660 fprintf(f
, "%d %d lineto %d %d lineto ", x2
, y2
, x1
, y2
);
3661 fprintf(f
, "closepath %.3f setgray fill 0 setgray\n", gray_level
);
3663 y2
-= 1; /* <y2> becomes the y pos to print at, <x1> the x pos.*/
3666 /* Type in the net names: */
3667 for (nl
= a
->nets
; nl
!= NULL
; nl
= nl
->next
)
3669 n
= nl
->this; /* Only print the net_under_study */
3670 if (net_name_located_p(net_under_study
, n
) == TRUE
)
3672 if ((x1
+ strlen(n
->name
)) <= x2
)
3674 ps_put_label(f
, n
->name
, (float)(x1
), (float)(y2
));
3675 x1
+= strlen(n
->name
) + 2;
3681 ps_put_label(f
, n
->name
, (float)(x1
), (float)(y2
));
3682 x1
+= strlen(n
->name
) + 2;
3688 else /* Print out the module icon */
3690 ps_print_mod(f
, a
->mod
);
3694 /*------------------------------------------------------------------------------------*/
3696 int check_terminal_p(ter
, ex
)
3700 if (ter
== ex
->t
) return(TRUE
);
3704 /*------------------------------------------------------------------------------------*/
3706 map_terminals_into_active_expansions(ml
, ActiveExpns
)
3707 mlist
*ml
; /* List of modules to expand on */
3708 expnlist
**ActiveExpns
;
3710 /* This takes a list of modules and digs out all of the terminals contained therein.
3711 These terminals are then mapped into the appropriate points on the appropriate
3712 edge structures. It is expected that the list of modules being routed is given
3714 Active expansions are the expansions associated with source (OUT|INOUT) terminals.
3715 Each active expansion is places on the <ActiveExpns> list for use in first_cut,
3716 etc. all inactive expansions make their first moves, and then wait to be located
3717 by the active expansions. (see first_cut, make next_best_move, etc..) */
3719 tilist
*tl
; /* Dummy tile list */
3720 tlist
*trl
, *trll
; /* terminal list */
3727 asg_arc
*tarc
, *ArcUsed
;
3729 for (mll
= ml
; mll
!= NULL
; mll
= mll
->next
)
3731 /* Walk through the list of terminals in each tile... */
3733 tarc
= (asg_arc
*)mod
->htile
->this; /* As set in 1st loop in "map_into_arcs" */
3735 /* For each terminal belonging to the module, create the expansion structure
3736 associated with it, and add this structure to the list of active terminals. */
3737 for (trl
= mod
->terms
; trl
!= NULL
; trl
= trl
->next
)
3741 /* Only create expansions for terminals that do not already have
3742 expansions created for them, and that have nets that can terminate
3743 (more than just one one terminal on the net) */
3744 if ((ter
->nt
!= NULL
) && (list_length(ter
->nt
->terms
) > 1) &&
3745 /* Not obvious... It is needed for partial routing of a schematic */
3746 (member_p(ter
, ter
->nt
->terms
, identity
) == TRUE
))
3748 /* If you've got one piece of a good net, get all of it */
3749 for(trll
= ter
->nt
->terms
; trll
!= NULL
; trll
= trll
->next
)
3751 if (member_p(trll
->this, *ActiveExpns
, check_terminal_p
)== FALSE
)
3753 oldExpns
= (expnlist
*)member(trll
->this, ter
->nt
->expns
,
3755 if ((oldExpns
== NULL
) &&
3756 (trll
->this->nt
!= NULL
)) /* Skip Specialized terminals */
3758 ex
= create_expansion(trll
->this);
3759 /* Save all expansions as 'Active' ones: (terminals) */
3760 push(ex
, ActiveExpns
);
3762 /* Otherwise look for old expansions to put on the list */
3765 pushnew(oldExpns
->this, ActiveExpns
);
3774 /*------------------------------------------------------------------------------------*/
3776 void set_file_and_net()
3778 /* This prompts the user and gets a filename to which the global route and expansion
3779 details are to be dumped. This sets the globals <df> and <net_under_study>. */
3781 strcpy(dfname
, "asg_groute.info");
3783 fprintf(stderr, "File to dump global route info to -> ");
3784 scanf("%s", dfname);
3787 if ((df
= fopen(dfname
, "w")) == NULL
)
3789 fprintf(stderr
,"can't open %s\n", dfname
);
3793 else fprintf(stderr
,"%s, used for global routing dump file\n", dfname
);
3795 sprintf(stderr
, "gnd");
3797 fprintf(stderr, "Please name the net being traced: ");
3798 scanf("%s", net_under_study);
3801 /* now start the dump file: */
3804 ps_print_standard_header(df
);
3805 fprintf(df
, "\n(%s: global route trace for net %s) %d %d %d %d init\n",
3806 getenv("USER"), net_under_study
, xfloor
, yfloor
, x_sizes
[0], y_sizes
[0]);
3810 ps_print_standard_header(df
);
3811 fprintf(df
, "swidth setlinewidth\n/Courier findfont fwidth scalefont setfont\n");
3812 fprintf(df
,"%%%%BoundingBox: %d %d %d %d\n",
3813 xfloor
- CHANNEL_LENGTH
, yfloor
- CHANNEL_HEIGHT
,
3814 x_sizes
[0] + CHANNEL_LENGTH
, y_sizes
[0] + CHANNEL_HEIGHT
);
3818 /*------------------------------------------------------------------------------------*/
3819 /*------------------------------------------------------------------------------------*/
3824 /* estimate the cost of the global route for this net: */
3825 expn
*ex
= (expn
*)n
->done
->this;
3830 for (trl
= ex
->connections
; trl
!= NULL
; trl
= trl
->next
)
3832 besTrail
= trl
->this;
3833 cost
+= trail_cost(besTrail
);
3838 /*------------------------------------------------------------------------------------*/
3840 int in_cost_order(n1
, n2
)
3843 /* order the two nets - the more expensive net goes to the left */
3844 if (net_cost(n1
) > net_cost(n2
)) return(TRUE
);
3848 /*------------------------------------------------------------------------------------*/
3850 void reset_net_structures(nl
)
3853 /* Remove any NULL Nets from the list.*/
3856 for (nll
= *nl
; nll
!= NULL
; nll
= nll
->next
)
3858 if (nll
->this->terms
!= NULL
)
3861 nll
->this->rflag
= NULL
;
3863 else rem_item(nll
->this, nl
);
3867 /*------------------------------------------------------------------------------------*/
3868 /*------------------------------------------------------------------------------------*/
3870 void create_routing_space(ml
, p
, xlen
, ylen
, xorg
, yorg
)
3874 /* This function creates the data structures used for global routing on the
3875 given page <p>. This should be called only once, and prior to the call
3876 to "first_global_route". */
3878 expnlist
*ActiveExpns
= NULL
; /* list of all active terminals */
3879 tilist
*allVSpace
= NULL
, *allHSpace
= NULL
;
3881 /* See 'BoundingBox' definition in "debug.c"; <routingRoot>s are globals */
3882 routingRoot
[HORZ
][p
] =
3883 create_tile(xlen
+ 2 * CHANNEL_LENGTH
+ 2 * TERM_MARGIN
,
3884 ylen
+ 2 * CHANNEL_HEIGHT
+ 2 * TERM_MARGIN
,
3886 xorg
- CHANNEL_LENGTH
- TERM_MARGIN
,
3887 yorg
- CHANNEL_LENGTH
- TERM_MARGIN
);
3889 routingRoot
[VERT
][p
] =
3890 create_tile(ylen
+ 2 * CHANNEL_HEIGHT
+ 2 * TERM_MARGIN
,
3891 xlen
+ 2 * CHANNEL_LENGTH
+ 2 * TERM_MARGIN
,
3893 yorg
- CHANNEL_HEIGHT
- TERM_MARGIN
,
3894 xorg
- CHANNEL_LENGTH
- TERM_MARGIN
);
3897 insert_all_modules(routingRoot
[HORZ
][p
], routingRoot
[VERT
][p
], ml
);
3899 /* the next stage is to create the structures that are used to control this
3900 * stage of the routing process. */
3901 allHSpace
= allspace(routingRoot
[HORZ
][p
], &allHSpace
);
3902 allVSpace
= allspace(routingRoot
[VERT
][p
], &allVSpace
);
3904 reform_tile_space(allHSpace
, HORZ
);
3905 reform_tile_space(allVSpace
, VERT
);
3907 /* Assign the global 'solidp' function for insertions, now that the tile-space
3908 has been reformed */
3909 solidp
= solidp_for_arcs
;
3911 reset_net_structures(&nets
);
3914 /*------------------------------------------------------------------------------------*/
3916 nlist
*first_global_route(ml
, p
, onceOnly
, congestionRule
)
3918 int p
, onceOnly
, congestionRule
;
3920 /* This function performs the global routing for the circuit. This begins by
3921 evaluating where the available routing space is. */
3923 /* This fn must be called at least once */
3925 /* This function is meant to serve in two modes: Either for creating a completed
3926 route on a completed routing space (non-incremental-mode:<onceOnly> == FALSE),
3927 or for completing the first-pass global route for a route that will be
3928 incrementally added to. (<onceOnly> == TRUE) */
3930 expnlist
*expns
= NULL
, *exl
;
3931 nlist
*non_ripped
= NULL
, *nl
, *nll
, *ActiveNets
= NULL
;
3934 /* First, set the congestion evaluation function... */
3935 select_congestion_rule(congestionRule
);
3937 map_terminals_into_active_expansions(ml
, &expns
);
3939 /* Collect the nets that are being dealt with: */
3940 for (exl
= expns
; exl
!= NULL
; exl
= exl
->next
)
3942 pushnew(exl
->this->n
, &ActiveNets
);
3945 if (debug_level
== 1) set_file_and_net();
3946 else if (debug_level
== 10) prepare_tile_spaces(FALSE
);
3947 else if (debug_level
== 11) prepare_tile_spaces(TRUE
);
3949 if (first_cut(expns
, p
) < 0) {
3954 if (onceOnly
== FALSE
)
3956 reset_all_trail_costs(ActiveNets
, p
);
3958 /* Remove any dummy terminals from the master netlist, as they can
3960 non_ripped
= (stopAtFirstCut
== TRUE
) ? NULL
:
3961 (nlist
*)delete_if(&ActiveNets
, no_terminals
);
3963 if (debug_level
>= 3)
3965 for (nl
= non_ripped
; nl
!= NULL
; nl
= nl
->next
)
3966 fprintf(stderr
,"cost for net <%s> is %d\n",
3967 nl
->this->name
, net_cost(nl
->this));
3969 if (debug_level
>= 3)
3971 fprintf(stderr
, "..............First Cut at GR Completed..............\n");
3972 fprintf(stderr
, "Before Improvement...");
3973 dump_net_costs(ActiveNets
);
3976 /* Iteratively improve the route until all nets have been relaid once. */
3977 for(nl
= (nlist
*)sort_list(non_ripped
, in_cost_order
);
3978 nl
!= NULL
; nl
= nl
->next
)
3980 if(debug_level
>= 3)
3982 fprintf(stderr
,"\nBefore improving net <%s>:\n", nl
->this->name
);
3983 exl
= (expnlist
*)nl
->this->done
;
3984 long_dump_trails(exl
->this->connections
);
3987 /* worstArc = worst_arc_on_net(nl->this); */
3988 improve_route(nl
->this, p
);
3989 set_arc_costs(ActiveNets
);
3991 if (debug_level
>= 3)
3993 fprintf(stderr
, "\nAfter improving net %s:\n",
3995 exl
= (expnlist
*)nl
->this->done
;
3996 long_dump_trails(exl
->this->connections
);
3997 dump_net_costs(ActiveNets
);
4007 /*------------------------------------------------------------------------------------*/
4009 nlist
*incremental_global_route(newMods
, modsSoFar
, oldNets
, p
)
4010 mlist
*newMods
; /* Modules to be added to diagram */
4011 mlist
*modsSoFar
; /* Modules to form global route for */
4013 int p
; /* Virtual Page No. to add them to */
4015 /* This function performs the global routing for the circuit. This begins by
4016 evaluating where the available routing space is. */
4018 expnlist
*expns
= NULL
, *exl
;
4019 nlist
*non_ripped
= NULL
, *nl
, *ActiveNets
= NULL
;
4023 allow_for_further_routing(oldNets
, p
);
4025 add_modules(newMods
, p
);
4026 map_terminals_into_active_expansions(modsSoFar
, &expns
);
4028 /* Must collect ALL nets that are to be routed. */
4029 for (exl
= expns
; exl
!= NULL
; exl
= exl
->next
)
4031 pushnew(exl
->this->n
, &ActiveNets
);
4034 first_cut(expns
, p
);
4036 reset_all_trail_costs(ActiveNets
, p
);
4038 if (debug_level
>= 3) fprintf(stderr
, "...First Cut at Incremental GR Completed.\n");
4040 /* Remove any dummy terminals from the master netlist, as they can cause problems: */
4041 non_ripped
= (stopAtFirstCut
== TRUE
) ? NULL
:
4042 (nlist
*)delete_if(&ActiveNets
, no_terminals
);
4044 if(debug_level
>= 3)
4046 fprintf(stderr
, "Before Improvement...");
4047 dump_net_costs(ActiveNets
);
4050 /* Iteratively improve the route until all nets have been relaid at least once, or
4051 no improvement is found. */
4052 for(nl
= (nlist
*)sort_list(non_ripped
, in_cost_order
);
4053 nl
!= NULL
; nl
= nl
->next
)
4055 if(debug_level
>= 3)
4057 fprintf(stderr
,"\nBefore improving net <%s>:\n", nl
->this->name
);
4058 exl
= (expnlist
*)nl
->this->done
;
4059 long_dump_trails(exl
->this->connections
);
4062 /* worstArc = worst_arc_on_net(nl->this); */
4063 improve_route(nl
->this, worstArc
, p
);
4064 set_arc_costs(ActiveNets
);
4066 if(debug_level
>= 3)
4068 fprintf(stderr
,"\nAfter improving net <%s>:\n", nl
->this->name
);
4069 exl
= (expnlist
*)nl
->this->done
;
4070 long_dump_trails(exl
->this->connections
);
4071 dump_net_costs(ActiveNets
);
4081 /*------------------------------------------------------------------------------------*/
4083 void print_global_route(f
)
4086 /* for date and time */
4088 extern long int time();
4090 /* Define the bounding box for the post-script code: */
4091 fprintf(f
,"%%%%BoundingBox: %d %d %d %d\n",
4092 xfloor
- CHANNEL_LENGTH
, yfloor
- CHANNEL_HEIGHT
,
4093 x_sizes
[0] + CHANNEL_LENGTH
, y_sizes
[0] + CHANNEL_HEIGHT
);
4096 /* now dump the result */
4097 time_loc
= time(0L);
4099 if (latex
!= TRUE
) /* Not in latex mode */
4101 ps_print_standard_header(f
);
4102 fprintf(f
, "\n(N2A ?? %s %s %s)\n",
4103 getenv("USER"), ctime(&time_loc
),
4104 (stopAtFirstCut
== TRUE
) ? "(first cut only)" : "with rip-up");
4106 fprintf(f
, "(using flags-> rule #%d s:%d c:%d part:%d dir:%d)\n",
4107 partition_rule
, max_partition_size
, max_partition_conn
,
4108 partition_count
, matrix_type
);
4110 fprintf(f
,"%d %d %d %d init\n", xfloor
, yfloor
, x_sizes
[0], y_sizes
[0]);
4112 else /* This stuff replaces the init for latex mode */
4114 ps_print_standard_header(f
);
4115 fprintf(f
, "swidth setlinewidth\n/Courier findfont fwidth scalefont setfont\n");
4116 fprintf(f
,"%%%%BoundingBox: %d %d %d %d\n",
4117 xfloor
- CHANNEL_LENGTH
, yfloor
- CHANNEL_HEIGHT
,
4118 x_sizes
[0] + CHANNEL_LENGTH
, y_sizes
[0] + CHANNEL_HEIGHT
);
4121 ps_print_tile_space(routingRoot
[HORZ
][0], f
, ps_print_arc
, TRUE
);
4123 if (latex
!= TRUE
) fprintf(f
, "showpage\n");
4127 /*---------------------------------------------------------------------------------*/
4133 for(nl
=nets
; nl
!=NULL
; nl
= nl
->next
)
4135 fprintf(stderr
, "<%s>...", nl
->this->name
);
4137 fprintf(stderr
, "\n");
4140 /*---------------------------------------------------------------------------------*/
4142 dump_net_costs(nets
)
4146 for(nl
=nets
; nl
!=NULL
; nl
= nl
->next
)
4148 fprintf(stderr
, "<%s>=%d...", nl
->this->name
, net_cost(nl
->this));
4150 fprintf(stderr
, "\n");
4153 /*---------------------------------------------------------------------------------*/
4159 for(nl
=mods
; nl
!=NULL
; nl
= nl
->next
)
4161 fprintf(stderr
, "<%s>...", nl
->this->name
);
4163 fprintf(stderr
, "\n");
4166 /*---------------------------------------------------------------------------------*/
4167 /*---------------------------------------------------------------------------------*/
4172 asg_arc
*a
= (asg_arc
*)t
->this;
4173 if (a
->page
== HORZ
)
4174 fprintf(stderr
, "(%d,%d),(%d,%d)H...",
4175 t
->x_pos
, t
->y_pos
, t
->x_pos
+ t
->x_len
, t
->y_pos
+ t
->y_len
);
4177 fprintf(stderr
, "(%d,%d),(%d,%d)V...",
4178 t
->y_pos
, t
->x_pos
, t
->y_pos
+ t
->y_len
, t
->x_pos
+ t
->x_len
);
4181 /*---------------------------------------------------------------------------------*/
4186 tilist
*temp
= NULL
, *tl
;
4190 fprintf(stderr
, "\tn<%s> t<%s>-> ", t
->ex
->t
->nt
->name
, t
->ex
->t
->mod
->name
);
4194 fprintf(stderr
, "\tn<%s> t<%s> & <%s>-> ", t
->ex
->t
->nt
->name
,
4195 t
->ex
->t
->mod
->name
, t
->jEx
->t
->mod
->name
);
4197 temp
= (tilist
*)rcopy_list(t
->tr
);
4198 for (tl
= temp
; tl
!= NULL
; tl
= tl
->next
)
4200 fprintf(stderr
, "%x...", tl
->this);
4202 fprintf(stderr
, "[%d]...", list_length(temp
));
4207 /*------------------------------------------------------------------------------------*/
4209 dump_tiles(tilesToSee
)
4213 /* Dump Tile List to the screen: */
4214 for (tl
= tilesToSee
; tl
!= NULL
; tl
= tl
->next
)
4216 dump_tile(tl
->this);
4218 fprintf (stderr
, "\n");
4221 /*---------------------------------------------------------------------------------*/
4226 tilist
*temp
= NULL
, *tl
;
4230 fprintf(stderr
, "\tn<%s> t<%s>-> ", t
->ex
->t
->nt
->name
, t
->ex
->t
->mod
->name
);
4234 fprintf(stderr
, "\tn<%s> t<%s> & <%s>-> ", t
->ex
->t
->nt
->name
,
4235 t
->ex
->t
->mod
->name
, t
->jEx
->t
->mod
->name
);
4237 temp
= (tilist
*)rcopy_list(t
->tr
);
4239 fprintf(stderr
, "[%d]$%d...", list_length(temp
), trail_cost(t
));
4244 /*------------------------------------------------------------------------------------*/
4246 long_dump_trails(trailsToSee
)
4247 trlist
*trailsToSee
;
4250 /* Dump Trail List to the screen: */
4251 for (trl
= trailsToSee
; trl
!= NULL
; trl
= trl
->next
)
4253 long_dump_trail(trl
->this);
4254 fprintf (stderr
, "\n");
4256 fprintf (stderr
, "\n");
4259 /*------------------------------------------------------------------------------------*/
4261 dump_trails(trailsToSee
)
4262 trlist
*trailsToSee
;
4265 /* Dump Trail List to the screen: */
4266 for (trl
= trailsToSee
; trl
!= NULL
; trl
= trl
->next
)
4268 dump_trail(trl
->this);
4269 fprintf (stderr
, "\n");
4271 fprintf (stderr
, "\n");
4274 /*------------------------------------------------------------------------------------*/
4276 dump_arcs(arcsToSee
)
4281 /* Dump Arc List to the screen: */
4282 for (al
= arcsToSee
; al
!= NULL
; al
= al
->next
)
4285 if (al
->this->page
== HORZ
)
4286 fprintf(stderr
, "(%d,%d),(%d,%d)H...",
4287 t
->x_pos
, t
->y_pos
, t
->x_pos
+ t
->x_len
, t
->y_pos
+ t
->y_len
);
4289 fprintf(stderr
, "(%d,%d),(%d,%d)V...",
4290 t
->y_pos
, t
->x_pos
, t
->y_pos
+ t
->y_len
, t
->x_pos
+ t
->x_len
);
4292 fprintf (stderr
, "\n");
4295 /*-------------------------------------------------------------------------------------*/
4297 void prepare_tile_spaces(netFlag
)
4299 strcpy(dfname
, "asg_vtiles.info");
4301 fprintf(stderr, "File to dump vertical tiles to -> ");
4302 scanf("%s", dfname);
4304 if ((vf
= fopen(dfname
, "w")) == NULL
)
4306 fprintf(stderr
,"Sorry, can't open %s\n", dfname
);
4311 strcpy(dfname
, "asg_htiles.info");
4313 fprintf(stderr, "File to dump horizontal tiles to -> ");
4314 scanf("%s", dfname);
4316 if ((hf
= fopen(dfname
, "w")) == NULL
)
4318 fprintf(stderr
,"Sorry, can't open %s\n", dfname
);
4323 if (netFlag
== TRUE
)
4325 /* Get the net name to study: */
4326 strcpy(net_under_study
, "gnd");
4328 fprintf(stderr, "Please name the net being traced: ");
4329 scanf("%s", net_under_study);
4334 /*------------------------------------------------------------------------------------*/
4335 /* END OF FILE "global_route.c" */