1 /*------------------------------------------------------------\
2 |                                                             |
3 | This file is part of the Alliance CAD System Copyright      |
4 | (C) Laboratoire LIP6 - D�partement ASIM Universite P&M Curie|
5 |                                                             |
6 | Home page      : http://www-asim.lip6.fr/alliance/          |
7 | E-mail         : mailto:alliance-users@asim.lip6.fr       |
8 |                                                             |
9 | This progam is  free software; you can redistribute it      |
10 | and/or modify it under the  terms of the GNU Library General|
11 | Public License as published by the Free Software Foundation |
12 | either version 2 of the License, or (at your option) any    |
13 | later version.                                              |
14 |                                                             |
15 | Alliance VLSI  CAD System  is distributed  in the hope that |
16 | it  will be useful, but WITHOUT  ANY WARRANTY;              |
17 | without even the  implied warranty of MERCHANTABILITY or    |
18 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General       |
19 | Public License for more details.                            |
20 |                                                             |
21 | You should have received a copy  of the GNU General Public  |
22 | License along with the GNU C Library; see the file COPYING. |
23 | If not, write to the Free Software Foundation, Inc.,        |
24 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                     |
25 |                                                             |
26 \------------------------------------------------------------*/
27 /*------------------------------------------------------------\
28 |                                                             |
29 | Tool    :                     Scp                           |
30 |                                                             |
31 | File    :                 Scp Build                         |
32 |                                                             |
33 | Date    :                  04.03.98                         |
34 |                                                             |
35 \------------------------------------------------------------*/
36 /*------------------------------------------------------------\
37 |                                                             |
38 |                         Include Files                       |
39 |                                                             |
40 \------------------------------------------------------------*/
41 
42 # include <stdio.h>
43 # include <stdlib.h>
44 # include <string.h>
45 # include "mut.h"
46 # include "mlo.h"
47 # include "aut.h"
48 # include "scl.h"
49 
50 # include "scp.h"
51 # include "scpbuild.h"
52 
53 /*------------------------------------------------------------\
54 |                                                             |
55 |                           Constants                         |
56 |                                                             |
57 \------------------------------------------------------------*/
58 /*------------------------------------------------------------\
59 |                                                             |
60 |                            Types                            |
61 |                                                             |
62 \------------------------------------------------------------*/
63 /*------------------------------------------------------------\
64 |                                                             |
65 |                          Variables                          |
66 |                                                             |
67 \------------------------------------------------------------*/
68 /*------------------------------------------------------------\
69 |                                                             |
70 |                        Locals  Functions                    |
71 |                                                             |
72 \------------------------------------------------------------*/
73 
74  static int SchNetCompare();
75  static int CheckNetIntersection __P((chain_list *, schnet_list *));
76 
77 /*------------------------------------------------------------\
78 |                                                             |
79 |                Function  Loc Add Transparence               |
80 |                                                             |
81 \------------------------------------------------------------*/
82 
loc_add_transparence(Figure,Net)83 static schbox_list * loc_add_transparence( Figure, Net )
84 
85   schfig_list *Figure;
86   schnet_list *Net;
87 {
88   schbox_list *Box;
89   schcon_list *Con_in;
90   schcon_list *Con_out;
91 
92   Box = addschbox( Figure, "trans" );
93   SetSchBoxTransparence( Box );
94 
95   Con_in  = addschboxconin( Figure, Box, "i" );
96   Con_out = addschboxconout( Figure, Box, "o" );
97 
98   addschnetcon( Net, Con_out );
99   addschnetcon( Net, Con_in  );
100 
101   return ( Box );
102 }
103 
104 /*------------------------------------------------------------\
105 |                                                             |
106 |                Function Loc Destroy Transparence            |
107 |                                                             |
108 \------------------------------------------------------------*/
109 
loc_destroytransparence(Figure,Transparence)110 static void loc_destroytransparence( Figure, Transparence)
111 
112   schfig_list *Figure;
113   schbox_list *Transparence;
114 {
115   schnet_list *SchNet;
116   schwir_list *SchWire;
117 
118   SchNet = Transparence->CON_IN->NET;
119   SchWire = addschwir(Figure, SchNet);
120 
121   SchWire->X  = Transparence->X + Transparence->CON_IN->X_REL;
122   SchWire->Y  = Transparence->Y + Transparence->CON_IN->Y_REL;
123   SchWire->DX = Transparence->X + Transparence->CON_OUT->X_REL;
124   SchWire->DY = Transparence->Y + Transparence->CON_OUT->Y_REL;
125 }
126 
127 /*------------------------------------------------------------\
128 |                                                             |
129 |                Function Loc Destroy Cluster Net             |
130 |                                                             |
131 \------------------------------------------------------------*/
132 
loc_destroyclusternet(Figure,Cluster)133 static void loc_destroyclusternet( Figure, Cluster )
134 
135   schfig_list *Figure;
136   schbox_list *Cluster;
137 {
138   schnet_list  *SchNetIn;
139   schnet_list  *SchNetOut;
140   schwir_list  *SchWire;
141   schwir_list **PrevSchWire;
142 
143   SchNetIn  = Cluster->CON_IN->NET;
144   SchNetOut = Cluster->CON_OUT->NET;
145 
146   SchWire = addschwir( Figure, SchNetIn );
147 
148   SchWire->X  = Cluster->X + Cluster->CON_IN->X_REL;
149   SchWire->Y  = Cluster->Y + Cluster->CON_IN->Y_REL;
150   SchWire->DX = Cluster->X + Cluster->CON_OUT->X_REL;
151   SchWire->DY = Cluster->Y + Cluster->CON_OUT->Y_REL;
152 
153   PrevSchWire = &SchNetOut->WIRE;
154 
155   for ( SchWire  = SchNetOut->WIRE;
156         SchWire != (schwir_list *)0;
157         SchWire  = SchWire->NEXT )
158   {
159     SchWire->NET = SchNetIn;
160     PrevSchWire  = &SchWire->NEXT;
161   }
162 
163   *PrevSchWire    = SchNetIn->WIRE;
164   SchNetIn->WIRE  = SchNetOut->WIRE;
165   SchNetOut->WIRE = (schwir_list *)0;
166 }
167 
168 /*------------------------------------------------------------\
169 |                                                             |
170 |                    Function Loc Destroy Cluster             |
171 |                                                             |
172 \------------------------------------------------------------*/
173 
loc_destroycluster(Figure,Cluster)174 static void loc_destroycluster(Figure, Cluster )
175 
176   schfig_list *Figure;
177   schbox_list *Cluster;
178 {
179   schwir_list    *SchWire1;
180   schwir_list    *SchWire2;
181   schwir_list    *SchWire3;
182   schbox_list    *Box;
183   schbox_list    *BoxN;
184   schcon_list    *Con;
185   schcon_list    *BoxConIn;
186   schcon_list    *ConCast;
187   schnet_list    *SchNet;
188   schcon_list    *ClusterCon;
189   ptype_list     *ScanBox;
190   ptype_list     *HeadBox;
191   chain_list     *ScanCon;
192   long            LastDY;
193   long            CurrentDX;
194   long            Counter;
195   int             NumberBoxIn;
196   int             Middle;
197 
198 # ifdef DEBUG
199   fprintf( stdout, "loc_destroycluster %s\n", Cluster->NAME );
200 # endif
201 /*
202 ** Get the three boxes of the cluster
203 */
204   HeadBox = (ptype_list  *)Cluster->SOURCE;
205   Box     = (schbox_list *)HeadBox->DATA;
206   HeadBox = HeadBox->NEXT;
207 /*
208 ** Compute the position of the output box
209 */
210   Box->USER = (void *)Cluster->USER;
211   Box->X    = Cluster->X + Cluster->DX - Box->DX;
212   Box->Y   += Cluster->Y;
213 
214   for ( Con  = Box->CON_OUT;
215         Con != (schcon_list *)0;
216         Con  = Con->NEXT )
217   {
218     Con->X_REL = Box->DX + SCP_BOX_CON_X;
219 
220     ClusterCon = (schcon_list *)Con->USER;
221 
222     SchNet = Con->NET;
223 
224     for ( ScanCon  = SchNet->CON_NET;
225           ScanCon != (chain_list *)0;
226           ScanCon  = ScanCon->NEXT )
227     {
228       ConCast = (schcon_list *) ScanCon->DATA;
229 
230       if ( ConCast == ClusterCon )
231       {
232         ScanCon->DATA = (void *)Con;
233       }
234     }
235   }
236 
237   if ( IsSchBoxCluster( Box ) )
238   {
239     loc_destroycluster( Figure, Box );
240   }
241 
242   NumberBoxIn = Box->NUMBER_IN;
243 
244   Box->CON_IN = (schcon_list *)reverse( (chain_list *)Box->CON_IN );
245   BoxConIn    = Box->CON_IN;
246 
247   ScanBox   = HeadBox;
248   LastDY    = 0;
249   Counter   = 1;
250   Middle    = 1 + ( NumberBoxIn ) / 2;
251   CurrentDX = 0;
252 
253   while ( ScanBox != (ptype_list *)0 )
254   {
255     BoxN = (schbox_list *)ScanBox->DATA;
256 
257     if ( Counter != Middle )
258     {
259       if ( Counter > Middle )
260       {
261         CurrentDX--;
262       }
263       else
264       {
265         CurrentDX++;
266       }
267     }
268     else
269     if ( NumberBoxIn & 1 )
270     {
271       CurrentDX++;
272     }
273 
274     BoxN->USER = (void *)Cluster->USER;
275     BoxN->X    = Cluster->X;
276     BoxN->Y    = Cluster->Y + LastDY;
277 /*
278 ** Compute the position of output connectors of the N input box
279 */
280     for ( Con  = BoxN->CON_OUT;
281           Con != (schcon_list *)0;
282           Con  = Con->NEXT )
283     {
284       Con->X_REL = BoxN->DX + SCP_BOX_CON_X;
285     }
286 /*
287 ** Replace input connectors of the cluster by input connectors of the N box
288 */
289     for ( Con  = BoxN->CON_IN;
290           Con != (schcon_list *)0;
291           Con  = Con->NEXT )
292     {
293       ClusterCon = (schcon_list *)Con->USER;
294 
295       SchNet = Con->NET;
296 
297       for ( ScanCon  = SchNet->CON_NET;
298             ScanCon != (chain_list *)0;
299             ScanCon  = ScanCon->NEXT )
300       {
301         ConCast = (schcon_list *) ScanCon->DATA;
302 
303         if ( ConCast == ClusterCon )
304         {
305           ScanCon->DATA = (void *)Con;
306         }
307       }
308     }
309 /*
310 ** Compute wire from the output of BoxN to the input of Box
311 */
312     SchWire1 = addschwir( Figure, BoxN->CON_OUT->NET );
313 
314     SchWire1->X  = BoxN->X + BoxN->CON_OUT->X_REL;
315     SchWire1->Y  = BoxN->Y + BoxN->CON_OUT->Y_REL;
316     SchWire1->DX = Box->X  + BoxConIn->X_REL - (CurrentDX * SCP_CLUSTER_ROUTE_STEP_X);
317     SchWire1->DY = SchWire1->Y;
318 
319     SchWire2 = addschwir( Figure, BoxN->CON_OUT->NET );
320 
321     SchWire2->X  = SchWire1->DX;
322     SchWire2->Y  = SchWire1->DY;
323     SchWire2->DX = SchWire2->X;
324     SchWire2->DY = Box->Y  + BoxConIn->Y_REL;
325 
326     SchWire3 = addschwir( Figure, BoxN->CON_OUT->NET );
327 
328     SchWire3->X  = SchWire2->DX;
329     SchWire3->Y  = SchWire2->DY;
330     SchWire3->DX = Box->X  + BoxConIn->X_REL;
331     SchWire3->DY = SchWire3->Y;
332 
333     if ( IsSchBoxCluster( BoxN ) )
334     {
335       loc_destroycluster( Figure, BoxN );
336     }
337 
338     LastDY  += BoxN->DY;
339     BoxConIn = BoxConIn->NEXT;
340 
341     Counter++;
342     ScanBox  = ScanBox->NEXT;
343   }
344 
345   Box->CON_IN = (schcon_list *)reverse( (chain_list *)Box->CON_IN );
346 }
347 
348 /*------------------------------------------------------------\
349 |                                                             |
350 |                   Function  Loc Build Cluster               |
351 |                                                             |
352 \------------------------------------------------------------*/
353 
loc_buildcluster(Figure)354 static void loc_buildcluster( Figure )
355 
356   schfig_list *Figure;
357 {
358   schbox_list  *Box;
359   schbox_list  *SavBox;
360   schbox_list **PrevBox;
361   schcon_list  *SchCon;
362   schcon_list  *ConCast;
363   schcon_list  *ClusterCon;
364   schbox_list  *BoxN;
365   schcon_list  *ConN;
366   schbox_list  *Cluster;
367   schnet_list  *SchNet;
368   ptype_list   *HeadList;
369   ptype_list   *ScanList;
370   chain_list   *ScanChain;
371   char          Buffer[ 32 ];
372   int           Number;
373   int           FoundOne;
374   int           Go;
375 
376   Number  = 0;
377   PrevBox = &Figure->BOX;
378 
379   for ( Box  = Figure->BOX;
380         Box != (schbox_list *)0;
381         Box  = Box->NEXT )
382   {
383     PrevBox = &Box->NEXT;
384   }
385 
386   for ( Box  = Figure->BOX;
387         Box != (schbox_list *)0;
388         Box  = Box->NEXT )
389   {
390     Go = 1;
391 /*
392 ** Search a box with one output and two inputs minimum
393 */
394     if ( ( ! IsSchBoxClustered( Box ) ) &&
395          ( Box->NUMBER_IN  >= 1       ) &&
396          ( Box->NUMBER_OUT >= 1       ) )
397     {
398       HeadList = (ptype_list *)0;
399       FoundOne = 0;
400 
401       for ( ConN  = Box->CON_IN;
402             ConN != (schcon_list *)0;
403             ConN  = ConN->NEXT )
404       {
405 /*
406 ** if the input signal have more than one output or more than one input
407 ** => should create a box net
408 */
409         if ( ( ConN->NET->NUMBER_OUT != 1 ) ||
410              ( ConN->NET->NUMBER_IN  != 1 ) )
411         {
412           HeadList = addptype( HeadList, SCP_CLUSTER_BOX_NET, (void *)ConN );
413         }
414         else
415         {
416 /*
417 ** The input signal (with one input and one output) should be connected to a box
418 ** with only one output
419 */
420           for ( ScanChain  = ConN->NET->CON_NET;
421                 ScanChain != (chain_list *)0;
422                 ScanChain  = ScanChain->NEXT )
423           {
424             ConCast = (schcon_list *)ScanChain->DATA;
425 
426             if ( ConCast == ConN ) continue;
427 /*
428 ** The input of the input signal is a box
429 */
430             if ( ConCast->ROOT_TYPE == SCH_ROOT_CON_BOX )
431             {
432               BoxN = (schbox_list *)ConCast->ROOT;
433 
434               if ( BoxN->NUMBER_OUT != 1 )
435               {
436 /*
437 ** The input of the input signal is a box, and this box has more than one output
438 ** => should create a box net
439 */
440                 HeadList = addptype( HeadList, SCP_CLUSTER_BOX_NET, (void *)ConN );
441               }
442               else
443               {
444 /*
445 ** The input of the input signal is a box, and this box has only one output, we found it !
446 ** => this box will be part of the cluster
447 */
448                 HeadList = addptype( HeadList, SCP_CLUSTER_BOX, (void *)BoxN );
449                 FoundOne = 1;
450               }
451             }
452             else
453 /*
454 ** The input of the input signal is a primary input
455 ** => should create a box net
456 */
457             if ( ConCast->ROOT_TYPE == SCH_ROOT_CON_FIG )
458             {
459               HeadList = addptype( HeadList, SCP_CLUSTER_BOX_NET, (void *)ConN );
460             }
461             else
462             {
463               Go = 0; break;
464             }
465           }
466         }
467 
468         if ( ! Go ) break;
469       }
470 /*
471 ** Create a cluster with those N boxes !
472 */
473       if ( ( Go       == 1 ) &&
474            ( FoundOne == 1 ) )
475       {
476         SavBox      = Figure->BOX;
477         Figure->BOX = (schbox_list *)0;
478 
479         sprintf( Buffer, "cluster_%d", Number++ );
480 
481         Cluster     = addschbox( Figure, Buffer );
482         Figure->BOX = SavBox;
483 
484         *PrevBox = Cluster;
485         PrevBox  = &Cluster->NEXT;
486 
487         SetSchBoxCluster( Cluster );
488 
489         Cluster->SOURCE = (void *)HeadList;
490 
491         for ( ScanList  = HeadList;
492               ScanList != (ptype_list *)0;
493               ScanList  = ScanList->NEXT )
494         {
495 /*
496 ** Must create a cluster box net !
497 */
498           if ( ScanList->TYPE == SCP_CLUSTER_BOX_NET )
499           {
500             ConN = (schcon_list *)ScanList->DATA;
501 
502             sprintf( Buffer, "clustnet_%d", Number++ );
503             BoxN = addschbox( Figure, Buffer );
504 
505             SetSchBoxClusterNet( BoxN );
506 
507             SchCon  = addschboxconin( Figure , BoxN, ConN->NAME );
508             SchCon->NET = ConN->NET;
509 
510             for ( ScanChain  = SchCon->NET->CON_NET;
511                   ScanChain != (chain_list *)0;
512                   ScanChain  = ScanChain->NEXT )
513             {
514               ConCast = (schcon_list *)ScanChain->DATA;
515 
516               if ( ConCast == ConN )
517               {
518                 ScanChain->DATA = (void *)SchCon;
519               }
520             }
521 
522             SchCon = addschboxconout( Figure, BoxN, ConN->NAME );
523             SchNet = addschnet( Figure );
524 
525             addschnetcon( SchNet, SchCon );
526             addschnetcon( SchNet, ConN   );
527 
528             ScanList->DATA = (void *)BoxN;
529           }
530           else
531           {
532             BoxN = (schbox_list *)ScanList->DATA;
533           }
534 
535           SetSchBoxClustered( BoxN );
536 /*
537 ** Duplicates all inputs of the N input boxes in the cluster (in the same order)
538 */
539           BoxN->CON_IN = (schcon_list *)reverse( (chain_list *)BoxN->CON_IN );
540 
541           for ( SchCon  = BoxN->CON_IN;
542                 SchCon != (schcon_list *)0;
543                 SchCon  = SchCon->NEXT )
544           {
545             ClusterCon = addschboxconin( Figure, Cluster, SchCon->NAME );
546             SchNet = SchCon->NET;
547 
548             for ( ScanChain  = SchNet->CON_NET;
549                   ScanChain != (chain_list *)0;
550                   ScanChain  = ScanChain->NEXT )
551             {
552               ConCast = (schcon_list *)ScanChain->DATA;
553 
554               if ( ConCast == SchCon )
555               {
556                 ScanChain->DATA = (void *)ClusterCon;
557               }
558             }
559 
560             ClusterCon->NET = SchNet;
561 
562             SchCon->USER = (void *)ClusterCon;
563           }
564 
565           BoxN->CON_IN = (schcon_list *)reverse((chain_list *) BoxN->CON_IN );
566         }
567 
568         SetSchBoxClustered( Box );
569         Cluster->SOURCE = addptype( Cluster->SOURCE, SCP_CLUSTER_BOX, (void *)Box );
570 
571         Box->CON_OUT = (schcon_list *)reverse((chain_list *)Box->CON_OUT );
572 /*
573 ** Duplicates all outputs of the output box in the cluster (in the same order)
574 */
575         for ( SchCon  = Box->CON_OUT;
576               SchCon != (schcon_list *)0;
577               SchCon  = SchCon->NEXT )
578         {
579           ClusterCon = addschboxconout( Figure, Cluster, SchCon->NAME );
580           SchNet = SchCon->NET;
581 
582           for ( ScanChain  = SchNet->CON_NET;
583                 ScanChain != (chain_list *)0;
584                 ScanChain  = ScanChain->NEXT )
585           {
586             ConCast = (schcon_list *)ScanChain->DATA;
587 
588             if ( ConCast == SchCon )
589             {
590               ScanChain->DATA = (void *) ClusterCon;
591             }
592           }
593 
594           ClusterCon->NET = SchNet;
595           SchCon->USER = (void *)ClusterCon;
596         }
597 
598         Box->CON_OUT = (schcon_list *)reverse((chain_list *)Box->CON_OUT );
599       }
600       else
601       {
602         freeptype( HeadList );
603       }
604     }
605   }
606 
607 # ifdef DEBUG
608   for ( Box  = Figure->BOX;
609         Box != (schbox_list *)0;
610         Box  = Box->NEXT )
611   {
612     if ( IsSchBoxCluster( Box ) )
613     {
614       fprintf( stdout, "Cluster %s : ", Box->NAME );
615 
616       for ( ScanList  = Box->SOURCE;
617             ScanList != (ptype_list *)0;
618             ScanList  = ScanList->NEXT )
619       {
620         BoxN = (schbox_list *)ScanList->DATA;
621         fprintf( stdout, " %s ", BoxN->NAME );
622       }
623 
624       fprintf( stdout, "\n" );
625     }
626   }
627 # endif
628 }
629 
630 /*------------------------------------------------------------\
631 |                                                             |
632 |                  Function  Loc Build Place First            |
633 |                                                             |
634 \------------------------------------------------------------*/
635 
loc_buildplacefirst(Figure)636 static scpcol_list *loc_buildplacefirst( Figure )
637 
638   schfig_list    *Figure;
639 {
640   scpcol_list    *ColMax;
641   scpcel_list    *Cell;
642   scpcol_list    *Column;
643   schbox_list    *Box;
644   schcon_list    *Con;
645   long            MaxCumulY;
646   long            CumulY;
647 
648   MaxCumulY = 0;
649   ColMax    = HEAD_SCPCOL;
650 
651   for ( Column  = HEAD_SCPCOL;
652         Column != (scpcol_list *)0;
653         Column  = Column->NEXT )
654   {
655     CumulY = 0;
656 
657     for ( Cell  = Column->CELL;
658           Cell != (scpcel_list *)0;
659           Cell  = Cell->NEXT )
660     {
661       if ( Cell->TYPE == SCP_CEL_BOX )
662       {
663         Box     = (schbox_list *)Cell->ROOT;
664         Box->Y  = CumulY;
665         CumulY += Box->DY + SCP_BOX_STEP_Y;
666 
667         if ( Box->DX > Column->MAX_DX_CELL )
668         {
669           Column->MAX_DX_CELL = Box->DX;
670         }
671       }
672       else
673       if ( Cell->TYPE == SCP_CEL_CON )
674       {
675         Con        = (schcon_list *) Cell->ROOT;
676         Con->Y_REL = CumulY;
677         CumulY    += SCP_CON_STEP_Y;
678 
679         if ( Column->MAX_DX_CELL < SCP_CELL_MIN_DX )
680         {
681           Column->MAX_DX_CELL = SCP_CELL_MIN_DX;
682         }
683       }
684     }
685 
686     if ( MaxCumulY < CumulY )
687     {
688       ColMax    = Column;
689       MaxCumulY = CumulY;
690     }
691   }
692 
693   return ( ColMax );
694 }
695 
696 
697 /*------------------------------------------------------------\
698 |                                                             |
699 |                Function  Loc Build Place In                 |
700 |                                                             |
701 \------------------------------------------------------------*/
702 
loc_buildplacein(Figure,ColumnFrom,ColumnTo)703 static schfig_list *loc_buildplacein( Figure, ColumnFrom, ColumnTo )
704 
705   schfig_list    *Figure;
706   scpcol_list    *ColumnFrom;
707   scpcol_list    *ColumnTo;
708 {
709   scpcel_list    *CellTo;
710   schcon_list    *ConTo;
711   schbox_list    *BoxTo;
712 
713   scpcel_list    *CellFrom;
714   schbox_list    *BoxFrom;
715   schcon_list    *ConFrom;
716 
717   chain_list     *Chain;
718   char            Begin = 1;
719 
720   long            CumulY;
721 
722   for ( CellTo = ColumnTo->LAST_CELL; CellTo != (scpcel_list *)0; CellTo = CellTo->PREV )
723   {
724     if ( CellTo->TYPE == SCP_CEL_BOX )
725     {
726       BoxTo = (schbox_list *) CellTo->ROOT;
727 
728       for (ConTo = BoxTo->CON_IN; ConTo; ConTo = ConTo->NEXT )
729       {
730         for (Chain = ConTo->NET->CON_NET; Chain; Chain = Chain->NEXT )
731         {
732           ConFrom = (schcon_list *) Chain->DATA;
733 
734           if ( ( IsSchConInternal( ConFrom ) ) &&
735                ( IsSchConOut( ConFrom )      ) )
736           {
737             BoxFrom = (schbox_list *) ConFrom->ROOT;
738 
739             if ( (   IsSchBoxTaged( BoxFrom ) ) &&
740                  ( ! IsSchBoxPlaced(BoxFrom ) ) )
741             {
742               CellFrom = (scpcel_list *) BoxFrom->USER;
743               if (CellFrom->COL == ColumnFrom)
744               {
745                 if ( Begin )
746                 {
747                   /* juste une idee de grandeur */
748 
749                   CumulY = BoxTo->Y + 2 * (BoxFrom->DY) + (BoxTo->DY);
750                   Begin  = 0;
751                 }
752 
753                 if ( ( BoxTo->Y + ConTo->Y_REL - ConFrom->Y_REL + BoxFrom->DY) <= CumulY )
754                 {
755                   BoxFrom->Y = BoxTo->Y + ConTo->Y_REL - ConFrom->Y_REL;
756                 }
757                 else
758                 {
759                   BoxFrom->Y = CumulY - BoxFrom->DY;
760                 }
761 
762                 CumulY = BoxFrom->Y - 1;
763                 SetSchBoxPlaced( BoxFrom );
764               }
765             }
766           }
767 
768           if ( (   IsSchConExternal( ConFrom ) ) &&
769                (   IsSchConIn( ConFrom )       ) &&
770                ( ! IsSchConPlaced( ConFrom )   ) &&
771                (   IsSchConTaged( ConFrom )    ) )
772           {
773             CellFrom = (scpcel_list *) ConFrom->USER;
774 
775             if ( CellFrom->COL == ColumnFrom )
776             {
777               if ( ! IsSchConPlaced( ConFrom ) )
778               {
779                 ConFrom->Y_REL = ( BoxTo->Y + ConTo->Y_REL );
780                 SetSchConPlaced( ConFrom );
781               }
782             }
783           }
784         }
785       }
786     }
787   }
788 
789   return( Figure );
790 }
791 
792 /*------------------------------------------------------------\
793 |                                                             |
794 |                Function  Loc Build Place Out                |
795 |                                                             |
796 \------------------------------------------------------------*/
797 
loc_buildplaceout(Figure,ColumnFrom,ColumnTo)798 static schfig_list *loc_buildplaceout( Figure, ColumnFrom, ColumnTo )
799 
800   schfig_list *Figure;
801   scpcol_list *ColumnFrom;
802   scpcol_list *ColumnTo;
803 {
804   chain_list     *Chain;
805   unsigned char   Begin;
806 
807   schbox_list    *BoxFrom;
808   schcon_list    *ConFrom;
809   scpcel_list    *CellFrom;
810 
811   schcon_list    *ConTo;
812   scpcel_list    *CellTo;
813   schbox_list    *BoxTo;
814 
815   long            CumulY;
816 
817   /* LUDO 29/10/2004 */
818   CumulY = 0;
819   /* ODUL */
820 
821   Begin  = 1;
822 
823   for ( CellTo  = ColumnTo->LAST_CELL;
824         CellTo != (scpcel_list *)0;
825         CellTo  = CellTo->PREV )
826   {
827     if ( CellTo->TYPE == SCP_CEL_BOX )
828     {
829       BoxTo = (schbox_list *) CellTo->ROOT;
830 
831       for ( ConTo = BoxTo->CON_IN;
832             ConTo != (schcon_list *)0;
833             ConTo = ConTo->NEXT )
834       {
835         if ( IsSchBoxPlaced( BoxTo ) ) break;
836 
837         for ( Chain  = ConTo->NET->CON_NET;
838               Chain != (chain_list *)0;
839               Chain  = Chain->NEXT )
840         {
841           if ( IsSchBoxPlaced( BoxTo ) ) break;
842 
843           ConFrom = (schcon_list *) Chain->DATA;
844 
845           if ( ConFrom != ConTo )
846           {
847             if ( ( IsSchConInternal( ConFrom ) ) &&
848                  ( IsSchConOut( ConFrom )      ) )
849             {
850               BoxFrom = (schbox_list *) ConFrom->ROOT;
851 
852               if ( IsSchBoxTaged( BoxFrom ) )
853               {
854                 CellFrom = (scpcel_list *) BoxFrom->USER;
855 
856                 if ( CellFrom->COL == ColumnFrom )
857                 {
858                   if ( Begin )
859                   {
860                     CumulY = BoxFrom->Y + 2 * (BoxTo->DY + BoxFrom->DY);
861                     Begin = 0;
862                   }
863 
864                   if ( ( BoxFrom->Y + ConFrom->Y_REL - ConTo->Y_REL + BoxTo->DY) <= CumulY )
865                   {
866                     SetSchBoxPlaced( BoxTo );
867                     BoxTo->Y = BoxFrom->Y + ConFrom->Y_REL - ConTo->Y_REL;
868                     CumulY = BoxTo->Y - 1;
869                   }
870                   else
871                   {        /* BoxTo->Y =  CumulY-BoxTo->DY; */
872                   }
873                 }
874               }
875             }
876           }
877         }
878       }
879 
880       if ( ! IsSchBoxPlaced( BoxTo ) )
881       {
882         /* LUDO Bug fix 29/10/2004 */
883         if ( Begin )
884         {
885           CumulY = BoxTo->Y;
886         }
887         /* ODUL */
888         else
889         {
890           BoxTo->Y = CumulY - BoxTo->DY;
891           SetSchBoxPlaced( BoxTo );
892           CumulY = BoxTo->Y - 1;
893         }
894       }
895     }
896 
897     if ( CellTo->TYPE == SCP_CEL_CON )
898     {
899       ConTo = (schcon_list *) CellTo->ROOT;
900 
901       for ( Chain  = ConTo->NET->CON_NET;
902             Chain != (chain_list *)0;
903             Chain = Chain->NEXT )
904       {
905         if ( IsSchConPlaced( ConTo ) ) break;
906 
907         ConFrom = (schcon_list *)Chain->DATA;
908 
909         if ( ConFrom != ConTo )
910         {
911           if ( ( IsSchConInternal( ConFrom ) ) &&
912                ( IsSchConOut( ConFrom      ) ) )
913           {
914             BoxFrom = (schbox_list *) ConFrom->ROOT;
915 
916             if ( IsSchBoxTaged( BoxFrom ) )
917             {
918               CellFrom = (scpcel_list *) BoxFrom->USER;
919 
920               if ( CellFrom->COL == ColumnFrom )
921               {
922                 if ( Begin )
923                 {
924                   CumulY = BoxFrom->Y + 2 * (BoxFrom->DY);
925                   Begin = 0;
926                 }
927 
928                 if ( ( BoxFrom->Y + ConFrom->Y_REL + 2 ) <= CumulY )
929                 {
930                   SetSchConPlaced(ConTo);
931                   ConTo->Y_REL = BoxFrom->Y + ConFrom->Y_REL;
932                   CumulY = ConTo->Y_REL - 1;
933                 }
934                 else
935                 {        /* ConTo->Y_REL =  CumulY; */
936                 }
937               }
938             }
939           }
940         }
941       }
942 
943       if ( Begin && IsSchConPlaced( ConTo ) )
944       {
945         ConTo->Y_REL = CumulY;
946         SetSchConPlaced(ConTo);
947         CumulY = ConTo->Y_REL - 1;
948 
949         /* LUDO 29/10/2004 */
950         Begin = 0;
951         /* ODUL */
952       }
953     }
954   }
955 
956   return (Figure);
957 }
958 
959 /*------------------------------------------------------------\
960 |                                                             |
961 |                  Function  Loc Build Place                  |
962 |                                                             |
963 \------------------------------------------------------------*/
964 
loc_buildplace(Figure)965 static schfig_list *loc_buildplace( Figure )
966 
967   schfig_list *Figure;
968 {
969   scpcol_list    *Column;
970   scpcol_list    *MaxColumn;
971 
972   MaxColumn = loc_buildplacefirst( Figure );
973 
974   for ( Column = MaxColumn; Column->NEXT; Column = Column->NEXT )
975   {
976     loc_buildplaceout( Figure, Column, Column->NEXT );
977   }
978 
979   HEAD_SCPCOL = (scpcol_list *)reverse( (chain_list *)HEAD_SCPCOL );
980 
981   for ( Column = MaxColumn; Column->NEXT; Column = Column->NEXT )
982   {
983     loc_buildplacein(Figure, Column->NEXT, Column);
984   }
985 
986   HEAD_SCPCOL = (scpcol_list *)reverse((chain_list *)HEAD_SCPCOL );
987 
988   return ( Figure );
989 }
990 
991 /*------------------------------------------------------------\
992 |                                                             |
993 |                 Function  Loc Routage Canal                 |
994 |                                                             |
995 \------------------------------------------------------------*/
996 
loc_routage_canal(Figure,ColumnFrom,ColumnTo,Xdep)997 static long loc_routage_canal( Figure, ColumnFrom, ColumnTo, Xdep )
998 
999   schfig_list    *Figure;
1000   scpcol_list    *ColumnFrom;
1001   scpcol_list    *ColumnTo;
1002   long            Xdep;
1003 {
1004   scpcel_list    *ScanCell;
1005   schbox_list    *SchBox;
1006   schnet_list    *SchNet;
1007   schnet_list   **SchNetTable;
1008   schwir_list    *SchWire;
1009   schcon_list    *ScanCon;
1010   schcon_list    *SchCon;
1011   chain_list     *SchNetList = NULL;
1012   chain_list     *CurChannelNets = NULL;
1013   chain_list     *ptchain;
1014   long            numschnet = 0;
1015   long            channel;
1016   long            i = 0;
1017 
1018   Xdep += ColumnFrom->MAX_DX_CELL;
1019 
1020   /* Traverse Canal Input and Output Connectors to */
1021   /* obtain list of SchNets in Canal and their     */
1022   /* vertical extremities with direction           */
1023 
1024   /* Channel Input Connectors */
1025 
1026   for ( ScanCell  = ColumnFrom->CELL;
1027         ScanCell != (scpcel_list *)0;
1028         ScanCell  = ScanCell->NEXT )
1029   {
1030       if ( ScanCell->TYPE == SCP_CEL_BOX )
1031       {
1032           SchBox = (schbox_list *) ScanCell->ROOT;
1033           for (ScanCon = SchBox->CON_OUT; ScanCon; ScanCon = ScanCon->NEXT ) {
1034               SchNet = ScanCon->NET;
1035               if (!IsSchNetCanal(SchNet)) {
1036                   numschnet++;
1037                   SetSchNetCanal(SchNet);
1038                   SchNetList = addchain(SchNetList, SchNet);
1039                   SchNet->YMAX = SchBox->Y + ScanCon->Y_REL;
1040                   SchNet->YMIN = SchBox->Y + ScanCon->Y_REL;
1041               }
1042               else if ((SchBox->Y + ScanCon->Y_REL) > (SchNet->YMAX)) {
1043                   SchNet->YMAX = SchBox->Y + ScanCon->Y_REL;
1044               }
1045               else if ((SchBox->Y + ScanCon->Y_REL) < (SchNet->YMIN)) {
1046                   SchNet->YMIN = SchBox->Y + ScanCon->Y_REL;
1047               }
1048           }
1049       }
1050       else if (ScanCell->TYPE == SCP_CEL_CON)
1051       {
1052           SchCon = (schcon_list *) ScanCell->ROOT;
1053 
1054           SchNet = SchCon->NET;
1055           if (!IsSchNetCanal(SchNet)) {
1056               numschnet++;
1057               SetSchNetCanal(SchNet);
1058               SchNetList = addchain(SchNetList, SchNet);
1059               SchNet->YMAX = SchCon->Y_REL;
1060               SchNet->YMIN = SchCon->Y_REL;
1061           }
1062           if ((SchCon->Y_REL) > (SchNet->YMAX)) {
1063               SchNet->YMAX = SchCon->Y_REL;
1064           }
1065           if ((SchCon->Y_REL) < (SchNet->YMIN)) {
1066               SchNet->YMIN = SchCon->Y_REL;
1067           }
1068       }
1069     }
1070 
1071     /* Channel Output connectors */
1072 
1073     for (ScanCell = ColumnTo->CELL; ScanCell; ScanCell = ScanCell->NEXT ) {
1074         if (ScanCell->TYPE == SCP_CEL_BOX) {
1075             SchBox = (schbox_list *) ScanCell->ROOT;
1076             for (ScanCon = SchBox->CON_IN; ScanCon; ScanCon = ScanCon->NEXT ) {
1077                 SchNet = ScanCon->NET;
1078                 if (!IsSchNetCanal(SchNet)) {
1079                     numschnet++;
1080                     SetSchNetCanal(SchNet);
1081                     SchNetList = addchain(SchNetList, SchNet);
1082                     SchNet->YMAX = SchBox->Y + ScanCon->Y_REL;
1083                     SetSchNetMaxOutput(SchNet);
1084                     SchNet->YMIN = SchBox->Y + ScanCon->Y_REL;
1085                     SetSchNetMinOutput(SchNet);
1086                 }
1087                 else if ((SchBox->Y + ScanCon->Y_REL) > (SchNet->YMAX)) {
1088                     SchNet->YMAX = SchBox->Y + ScanCon->Y_REL;
1089                     SetSchNetMaxOutput(SchNet);
1090                 }
1091                 else if ((SchBox->Y + ScanCon->Y_REL) < (SchNet->YMIN)) {
1092                     SchNet->YMIN = SchBox->Y + ScanCon->Y_REL;
1093                     SetSchNetMinOutput(SchNet);
1094                 }
1095             }
1096         }
1097         else if (ScanCell->TYPE == SCP_CEL_CON) {
1098             SchCon = (schcon_list *) ScanCell->ROOT;
1099 
1100             SchNet = SchCon->NET;
1101             if (!IsSchNetCanal(SchNet)) {
1102                 numschnet++;
1103                 SetSchNetCanal(SchNet);
1104                 SchNetList = addchain(SchNetList, SchNet);
1105                 SchNet->YMAX = SchCon->Y_REL;
1106                 SetSchNetMaxOutput(SchNet);
1107                 SchNet->YMIN = SchCon->Y_REL;
1108                 SetSchNetMinOutput(SchNet);
1109             }
1110             if ((SchCon->Y_REL) > (SchNet->YMAX)) {
1111                 SchNet->YMAX = SchCon->Y_REL;
1112                 SetSchNetMaxOutput(SchNet);
1113             }
1114             if ((SchCon->Y_REL) < (SchNet->YMIN)) {
1115                 SchNet->YMIN = SchCon->Y_REL;
1116                 SetSchNetMinOutput(SchNet);
1117             }
1118         }
1119     }
1120 
1121     /* build table of SchNets and sort */
1122 
1123     SchNetTable = (schnet_list **) autallocblock( (1 + numschnet ) * sizeof(schnet_list *));
1124     for (ptchain = SchNetList; ptchain; ptchain = ptchain->NEXT ) {
1125         SchNetTable[i++] = (schnet_list *) ptchain->DATA;
1126     }
1127     qsort(SchNetTable, numschnet, sizeof(schnet_list *), SchNetCompare);
1128 
1129     /* Allocate a channel number to each SchNet */
1130 
1131     channel = Xdep + 4;
1132     for (i = 0; i < numschnet; i++) {
1133         if ((SchNetTable[i])->YMAX == (SchNetTable[i])->YMIN) {
1134             (SchNetTable[i])->CANAL = channel;
1135             continue;
1136         }
1137         if (CheckNetIntersection(CurChannelNets, SchNetTable[i])) {
1138             channel += 2;
1139             if (CurChannelNets)
1140                 freechain(CurChannelNets);
1141             CurChannelNets = addchain(NULL, SchNetTable[i]);
1142         }
1143         else
1144             CurChannelNets = addchain(CurChannelNets, SchNetTable[i]);
1145         (SchNetTable[i])->CANAL = channel;
1146     }
1147     mbkfree(SchNetTable);
1148 
1149     /* Draw horizontal wires from input column to vertical wire */
1150 
1151     for (ScanCell = ColumnFrom->CELL; ScanCell; ScanCell = ScanCell->NEXT ) {
1152         if (ScanCell->TYPE == SCP_CEL_BOX) {
1153             SchBox = ScanCell->ROOT;
1154 
1155             for (ScanCon = SchBox->CON_OUT; ScanCon; ScanCon = ScanCon->NEXT ) {
1156                 SchNet = ScanCon->NET;
1157                 SchWire = addschwir(Figure, SchNet);
1158                 SchWire->X = SchBox->X + ScanCon->X_REL;
1159                 SchWire->DX = SchNet->CANAL;
1160                 SchWire->Y = SchBox->Y + ScanCon->Y_REL;
1161                 SchWire->DY = SchBox->Y + ScanCon->Y_REL;
1162             }
1163         }
1164         else if (ScanCell->TYPE == SCP_CEL_CON) {
1165             SchCon = (schcon_list *) ScanCell->ROOT;
1166             SchNet = SchCon->NET;
1167             SchWire = addschwir(Figure, SchNet);
1168             /* ICI LUDO
1169             SchWire->X = SchCon->X_REL + 2;
1170             */
1171             SchWire->X  = SchCon->X_REL;
1172             SchWire->DX = SchNet->CANAL;
1173             SchWire->Y  = SchCon->Y_REL;
1174             SchWire->DY = SchCon->Y_REL;
1175         }
1176     }
1177 
1178     /* Draw horizontal wires from vertical wire to output column */
1179 
1180     for (ScanCell = ColumnTo->CELL; ScanCell; ScanCell = ScanCell->NEXT ) {
1181         if (ScanCell->TYPE == SCP_CEL_BOX) {
1182             SchBox = ScanCell->ROOT;
1183             SchBox->X = channel + 6 + (ColumnTo->MAX_DX_CELL - SchBox->DX) / 2;
1184 
1185             for (ScanCon = SchBox->CON_IN; ScanCon; ScanCon = ScanCon->NEXT ) {
1186                 SchNet = ScanCon->NET;
1187                 SchWire = addschwir(Figure, SchNet);
1188                 SchWire->X = SchBox->X + ScanCon->X_REL;
1189                 SchWire->DX = SchNet->CANAL;
1190                 SchWire->Y = SchBox->Y + ScanCon->Y_REL;
1191                 SchWire->DY = SchBox->Y + ScanCon->Y_REL;
1192             }
1193         }
1194         else if (ScanCell->TYPE == SCP_CEL_CON) {
1195             SchCon = (schcon_list *) ScanCell->ROOT;
1196             SchCon->X_REL = channel + 6;
1197 
1198             SchNet = SchCon->NET;
1199             SchWire = addschwir(Figure, SchNet);
1200             /* ICI LUDO
1201             SchWire->X = SchCon->X_REL - 2;
1202             */
1203             SchWire->X  = SchCon->X_REL;
1204             SchWire->DX = SchNet->CANAL;
1205             SchWire->Y  = SchCon->Y_REL;
1206             SchWire->DY = SchCon->Y_REL;
1207         }
1208     }
1209 
1210     /* Draw vertical wires */
1211 
1212     for (ptchain = SchNetList; ptchain; ptchain = ptchain->NEXT ) {
1213         SchNet = (schnet_list *) ptchain->DATA;
1214         ClearSchNetCanal(SchNet);
1215         ClearSchNetDir(SchNet);
1216         if (SchNet->YMIN == SchNet->YMAX)
1217             continue;
1218         SchWire = addschwir(Figure, SchNet);
1219         SchWire->X = SchNet->CANAL;
1220         SchWire->DX = SchNet->CANAL;
1221         SchWire->Y = SchNet->YMIN;
1222         SchWire->DY = SchNet->YMAX;
1223     }
1224     freechain(SchNetList);
1225 
1226     return (channel + 6);
1227 }
1228 
1229 static int
SchNetCompare(net1,net2)1230 SchNetCompare(net1, net2)
1231     schnet_list   **net1;
1232     schnet_list   **net2;
1233 {
1234     long            type1, type2;
1235 
1236     type1 = GetSchNetDirType(*net1);
1237     type2 = GetSchNetDirType(*net2);
1238 
1239     if (type1 > type2)
1240         return (1);
1241     if (type1 < type2)
1242         return (-1);
1243 
1244     switch (type1) {
1245     case 0:
1246         return (((*net1)->YMAX - (*net1)->YMIN) - ((*net2)->YMAX - (*net2)->YMIN));
1247         break;
1248     case SCH_NET_MINDIR:
1249         return ((*net1)->YMIN - (*net2)->YMIN);
1250         break;
1251     case SCH_NET_MAXDIR:
1252         return ((*net2)->YMAX - (*net1)->YMAX);
1253         break;
1254     case SCH_NET_MAXDIR | SCH_NET_MINDIR:
1255         return (((*net2)->YMAX - (*net2)->YMIN) - ((*net1)->YMAX - (*net1)->YMIN));
1256         break;
1257     }
1258     return 0;
1259 }
1260 
1261 static int
CheckNetIntersection(NetList,Net)1262 CheckNetIntersection(NetList, Net)
1263     chain_list     *NetList;
1264     schnet_list    *Net;
1265 {
1266     chain_list     *ptchain;
1267     schnet_list    *CmpNet;
1268 
1269     for (ptchain = NetList; ptchain; ptchain = ptchain->NEXT ) {
1270         CmpNet = (schnet_list *) ptchain->DATA;
1271         if (Net->YMIN > CmpNet->YMAX || Net->YMAX < CmpNet->YMIN)
1272             continue;
1273         else
1274             break;
1275     }
1276     if (ptchain != NULL)
1277         return 1;
1278     else
1279         return 0;
1280 }
1281 
1282 /*------------------------------------------------------------\
1283 |                                                             |
1284 |                      Function  Loc Route                    |
1285 |                                                             |
1286 \------------------------------------------------------------*/
1287 
loc_route(Figure)1288 static schfig_list *loc_route( Figure )
1289 
1290   schfig_list *Figure;
1291 {
1292   scpcol_list *Column_from;
1293   scpcol_list *Column_to;
1294   long         Xdep;
1295 
1296   Xdep = 0;
1297 
1298   if ( HEAD_SCPCOL != (scpcol_list *)0 )
1299   {
1300     for ( Column_from        = HEAD_SCPCOL;
1301           Column_from->NEXT != (scpcol_list *)0;
1302           Column_from        = Column_from->NEXT )
1303     {
1304       Column_to = Column_from->NEXT;
1305       Xdep      = loc_routage_canal( Figure, Column_from, Column_to, Xdep );
1306     }
1307   }
1308 
1309   return (Figure);
1310 }
1311 
1312 /*------------------------------------------------------------\
1313 |                                                             |
1314 |                   Function  Loc Test Trans                  |
1315 |                                                             |
1316 \------------------------------------------------------------*/
1317 
loc_test_trans(Net,Column)1318 static int loc_test_trans( Net, Column )
1319 
1320   schnet_list *Net;
1321   scpcol_list *Column;
1322 {
1323   scpcel_list *ScpCel;
1324   schcon_list *SchCon;
1325   schbox_list *SchBox;
1326   chain_list  *ChainCon;
1327 
1328   for ( ChainCon  = Net->CON_NET;
1329         ChainCon != (chain_list *)0;
1330         ChainCon  = ChainCon->NEXT )
1331   {
1332     SchCon = (schcon_list *) ChainCon->DATA;
1333 
1334     if ( IsSchConInternal( SchCon ) )
1335     {
1336       SchBox = (schbox_list *) SchCon->ROOT;
1337 
1338       if ( IsSchBoxTransparence( SchBox ) )
1339       {
1340         ScpCel = (scpcel_list *) SchBox->USER;
1341 
1342         if ( ScpCel->COL == Column ) return( 0 );
1343       }
1344     }
1345   }
1346 
1347   return( 1 );
1348 }
1349 
1350 
1351 /*------------------------------------------------------------\
1352 |                                                             |
1353 |               Function  Loc Placement Initial               |
1354 |                                                             |
1355 \------------------------------------------------------------*/
1356 
loc_placement_initial(Figure)1357 static schfig_list *loc_placement_initial( Figure )
1358 
1359   schfig_list *Figure;
1360 {
1361   int             cpt_transparence;
1362 
1363   int             cpt;
1364   schcon_list    *Con;
1365   schcon_list    *Con2;
1366   chain_list     *Chain;
1367 
1368   schbox_list    *Box;
1369   schbox_list    *Box2;
1370   schbox_list    *Box4;
1371   scpcol_list    *Column2;
1372   scpcol_list    *Column;
1373   scpcel_list    *Cell;
1374   scpcel_list    *Cell2;
1375 
1376   schbox_list    *BoxBox4;
1377   scpcel_list    *BoxCell2;
1378   schcon_list    *BoxCon;
1379   schcon_list    *BoxCon2;
1380   chain_list     *BoxChain;
1381 
1382 
1383   /* connecteurs externes de sortie dans la premiere colonne */
1384 
1385   Column2 = addscpcol();
1386   Column = addscpcol();
1387 
1388   for ( Con  = Figure->CON_OUT;
1389         Con != (schcon_list *)0;
1390         Con  = Con->NEXT )
1391   {
1392     addschcontoscpcel( Con, addscpcel( Column2 ) );
1393 
1394     for ( Chain  = Con->NET->CON_NET;
1395           Chain != (chain_list *)0;
1396           Chain  = Chain->NEXT )
1397     {
1398       if ( loc_test_trans( Con->NET, Column ) )
1399       {
1400         Box2 = loc_add_transparence( Figure, Con->NET );
1401         SetSchBoxTaged(Box2);
1402         Cell2 = addscpcel(Column);
1403         addschboxtoscpcel(Box2, Cell2);
1404       }
1405     }
1406   }
1407 
1408   /* LUDO 29/10/2004 */
1409   cpt_transparence = 0;
1410   /* ODUL */
1411 
1412   while (cpt_transparence != Column->NUMBER_CELL) {
1413 
1414       Column2 = Column;
1415       Column = addscpcol();
1416 
1417       cpt = Column2->NUMBER_CELL;
1418       cpt_transparence = 0;
1419 
1420       for (Cell = Column2->CELL;
1421            Cell != (scpcel_list *)0;
1422            Cell = Cell->NEXT ) {
1423           if (Cell->TYPE == SCP_CEL_BOX) {
1424               Box = (schbox_list *) Cell->ROOT;
1425               SetSchBoxReTaged(Box);
1426           }
1427       }
1428 
1429       for (Cell = Column2->LAST_CELL;
1430            cpt != 0;
1431            Cell = (scpcel_list *) Cell->PREV) {
1432           cpt--;
1433           if (Cell->TYPE == SCP_CEL_BOX) {
1434               Box = (schbox_list *) Cell->ROOT;
1435 
1436               for (Con = Box->CON_IN;
1437                    Con != (schcon_list *)0;
1438                    Con = Con->NEXT ) {
1439                   for (Chain = Con->NET->CON_NET;
1440                        Chain != (chain_list *)0;
1441                        Chain = Chain->NEXT ) {
1442                       Con2 = (schcon_list *) Chain->DATA;
1443 
1444                       if (Con != Con2) {
1445                           if (IsSchConIn(Con2) && IsSchConInternal(Con2)
1446                               && !IsSchBoxTaged((schbox_list *) Con2->ROOT)
1447                               && loc_test_trans(Con->NET, Column)) {
1448                               Box4 = loc_add_transparence(Figure, Con2->NET);
1449                               Box4->NAME = namealloc("In_int_not_tag");
1450                               SetSchBoxTaged(Box4);
1451                               Cell2 = addscpcel(Column);
1452                               addschboxtoscpcel(Box4, Cell2);
1453                               cpt_transparence++;
1454                           }
1455 
1456                           if (IsSchConOut(Con2) && IsSchConInternal(Con2)) {
1457                               Box4 = (schbox_list *) Con2->ROOT;
1458                               if (!IsSchBoxTaged(Box4)) {
1459                                   SetSchBoxTaged(Box4);
1460                                   Cell2 = addscpcel(Column);
1461                                   addschboxtoscpcel(Box4, Cell2);
1462 
1463                                   for (BoxCon = Box4->CON_IN;
1464                                        BoxCon != (schcon_list *)0;
1465                                        BoxCon = BoxCon->NEXT ) {
1466                                       for (BoxChain = BoxCon->NET->CON_NET;
1467                                            BoxChain != (chain_list *)0;
1468                                            BoxChain = BoxChain->NEXT ) {
1469                                           BoxCon2 = (schcon_list *) BoxChain->DATA;
1470 
1471                                           if (BoxCon != BoxCon2) {
1472                                               if (IsSchConInternal(BoxCon2)
1473                                                   && IsSchBoxTaged((schbox_list *) BoxCon2->ROOT)
1474                                                   && IsSchBoxReTaged((schbox_list *) BoxCon2->ROOT)
1475                                                   && loc_test_trans(BoxCon->NET, Column)) {
1476                                                   BoxBox4 = loc_add_transparence(Figure, BoxCon2->NET);
1477                                                   BoxBox4->NAME = namealloc("IN__Int_Tag");
1478                                                   SetSchBoxTaged(BoxBox4);
1479                                                   BoxCell2 = addscpcel(Column);
1480                                                   addschboxtoscpcel(BoxBox4, BoxCell2);
1481                                                   cpt_transparence++;
1482                                               }
1483                                           }
1484                                       }
1485                                   }
1486                                   for (BoxCon = Box4->CON_OUT;
1487                                        BoxCon != (schcon_list *)0;
1488                                        BoxCon = BoxCon->NEXT ) {
1489                                       for (BoxChain = BoxCon->NET->CON_NET;
1490                                            BoxChain != (chain_list *)0;
1491                                            BoxChain = BoxChain->NEXT ) {
1492                                           BoxCon2 = (schcon_list *) BoxChain->DATA;
1493 
1494                                           if (BoxCon != BoxCon2) {
1495                                               if (IsSchConIn(BoxCon2) && IsSchConInternal(BoxCon2)
1496                                                   && !IsSchBoxReTaged((schbox_list *) BoxCon2->ROOT)
1497                                                   && loc_test_trans(BoxCon->NET, Column)) {
1498                                                   BoxBox4 = loc_add_transparence(Figure, BoxCon2->NET);
1499                                                   BoxBox4->NAME = namealloc("OUT__In_Int_Tag");
1500                                                   SetSchBoxTaged(BoxBox4);
1501                                                   BoxCell2 = addscpcel(Column);
1502                                                   addschboxtoscpcel(BoxBox4, BoxCell2);
1503                                                   cpt_transparence++;
1504                                               }
1505                                           }
1506                                       }
1507                                   }
1508                               }
1509                           }
1510 
1511                           /* relier un connecteur d'entree */
1512 
1513                           if (IsSchConIn(Con2) && IsSchConExternal(Con2)
1514                               && loc_test_trans(Con->NET, Column)) {
1515                               Box4 = loc_add_transparence(Figure, Con2->NET);
1516                               SetSchBoxTaged(Box4);
1517                               Cell2 = addscpcel(Column);
1518                               addschboxtoscpcel(Box4, Cell2);
1519                               cpt_transparence++;
1520                           }
1521                       }
1522                   }
1523               }                /* for */
1524           }
1525       }
1526   }
1527   Column2 = Column;
1528   Column = addscpcol();
1529   cpt = Column2->NUMBER_CELL;
1530 
1531   for (Cell = Column2->LAST_CELL;
1532        cpt != 0;
1533        Cell = (scpcel_list *) Cell->PREV) {
1534       cpt--;
1535       if (Cell->TYPE == SCP_CEL_BOX) {
1536           Box = (schbox_list *) Cell->ROOT;
1537           Con2 = Box->CON_IN;
1538           for (Chain = Con2->NET->CON_NET;
1539                Chain != (chain_list *)0;
1540                Chain = Chain->NEXT ) {
1541               Con = (schcon_list *) Chain->DATA;
1542               if (IsSchConExternal(Con) && IsSchConIn(Con) && !IsSchConTaged(Con)) {
1543                   Cell2 = addscpcel(Column);
1544                   addschcontoscpcel(Con, Cell2);
1545                   SetSchConTaged(Con);
1546               }
1547           }
1548       }
1549   }
1550   return (Figure);
1551 }
1552 
1553 /*------------------------------------------------------------\
1554 |                                                             |
1555 |                    Function  Loc Build Box                  |
1556 |                                                             |
1557 \------------------------------------------------------------*/
1558 
loc_buildbox(Figure)1559 static schfig_list *loc_buildbox( Figure )
1560 
1561   schfig_list *Figure;
1562 {
1563   schbox_list    *Box;
1564   schbox_list    *Box0;
1565   schbox_list    *BoxN;
1566   schcon_list    *Con;
1567   ptype_list     *ScanBox;
1568   ptype_list     *HeadList;
1569   long            Y_cont1;
1570   long            Y_cont2;
1571   long            MiddleDY;
1572 //long            MiddleInDY;
1573   long            Delta;
1574   int             Number;
1575   int             NumberIn;
1576   int             NumberBoxIn0;
1577   int             NumberOut;
1578   int             Middle;
1579 
1580   for ( Box  = Figure->BOX;
1581         Box != (schbox_list *)0;
1582         Box  = Box->NEXT )
1583   {
1584 /*
1585 ** Compute the size of the box on Y
1586 */
1587     if ( IsSchBoxTransparence( Box ) )
1588     {
1589       Box->DY = SCP_BOX_TRANS_DY;
1590       Y_cont1 = SCP_BOX_TRANS_DY  / 2;
1591       Y_cont2 = SCP_BOX_TRANS_DY  / 2;
1592     }
1593     else
1594     {
1595       NumberIn  = Box->NUMBER_IN;
1596       NumberOut = Box->NUMBER_OUT;
1597 
1598       if ( NumberIn >= NumberOut )
1599       {
1600         Box->DY = ( 2 * SCP_BOX_CON_BASE_Y ) + ( ( NumberIn - 1 ) * SCP_BOX_CON_STEP_Y );
1601 
1602         Y_cont1 = Box->DY - SCP_BOX_CON_BASE_Y;
1603         Y_cont2 = Box->DY - SCP_BOX_CON_BASE_Y -
1604                   ( ( NumberIn - NumberOut ) * SCP_BOX_CON_STEP_Y / 2 );
1605       }
1606       else
1607       {
1608         Box->DY = ( 2 * SCP_BOX_CON_BASE_Y ) + ( ( NumberOut - 1 ) * SCP_BOX_CON_STEP_Y );
1609 
1610         Y_cont2 = Box->DY - SCP_BOX_CON_BASE_Y;
1611         Y_cont1 = Box->DY - SCP_BOX_CON_BASE_Y -
1612                   ( ( NumberOut - NumberIn ) * SCP_BOX_CON_STEP_Y / 2 );
1613       }
1614     }
1615 /*
1616 ** Compute the size of the box on X
1617 */
1618     if ( IsSchBoxCluster( Box ) )
1619     {
1620 /*
1621 ** Compute the size of the cluster on X
1622 */
1623       Box->DX   = 0;
1624 
1625       HeadList  = (ptype_list  *)Box->SOURCE;
1626       Box0      = (schbox_list *)HeadList->DATA;
1627       HeadList  = HeadList->NEXT;
1628 
1629       NumberBoxIn0 = 0;
1630 
1631       for ( ScanBox  = HeadList;
1632             ScanBox != (ptype_list *)0;
1633             ScanBox  = ScanBox->NEXT )
1634       {
1635         NumberBoxIn0++;
1636 
1637         BoxN = (schbox_list *)ScanBox->DATA;
1638 
1639         if ( Box->DX < BoxN->DX ) Box->DX = BoxN->DX;
1640       }
1641 
1642       Box->DX += Box0->DX + ( SCP_BOX_CON_X * 2 ) +
1643                  ( ( SCP_CLUSTER_ROUTE_STEP_X * NumberBoxIn0 ) / 2 ) + SCP_CLUSTER_ROUTE_STEP_X;
1644 /*
1645 ** Compute the position of the cluster's outputs on Y
1646 ** => The center of input boxes should be in front of the center of Box0's input connectors
1647 */
1648       Number   = 1;
1649       Middle   = NumberBoxIn0 / 2;
1650       MiddleDY = 0;
1651 /*
1652 ** Compute MiddleDY : the center of input boxes
1653 */
1654       for ( ScanBox  = HeadList;
1655             ScanBox != (ptype_list *)0;
1656             ScanBox  = ScanBox->NEXT )
1657       {
1658         BoxN = (schbox_list *)ScanBox->DATA;
1659         if ( Number <= Middle )
1660         {
1661           MiddleDY += BoxN->DY;
1662         }
1663         else
1664         {
1665           if ( NumberBoxIn0 & 1 ) MiddleDY += BoxN->DY / 2;
1666 
1667           break;
1668         }
1669 
1670         Number++;
1671       }
1672 /*
1673 ** Compute MiddleInDY : the center of Box0's input connectors
1674 */
1675       /* TO BE DONE */
1676       Number     = 1;
1677     //MiddleIn   = Box0->NUMBER_IN / 2;
1678     //MiddleInDY = SCP_BOX_CON_BASE_Y;
1679 
1680       for ( Con  = Box0->CON_IN;
1681             Con != (schcon_list *)0;
1682             Con  = Con->NEXT )
1683       {
1684         /* if ( Number < MiddleIn ) */
1685         /* { */
1686         /*   MiddleInDY += SCP_BOX_CON_STEP_Y; */
1687         /* } */
1688         /* else */
1689         /* { */
1690         /*   /\* if ( ! ( Box0->NUMBER_IN & 0x1 ) ) *\/ */
1691         /*   /\* { *\/ */
1692         /*   /\*   MiddleInDY += SCP_BOX_CON_STEP_Y / 2; *\/ */
1693         /*   /\* } *\/ */
1694 
1695         /*   break; */
1696         /* } */
1697 
1698         Number++;
1699       }
1700 
1701       /*
1702       MiddleInDY = Box0->DY - MiddleInDY;
1703       Delta      = MiddleDY - ( Box->DY / 2 );
1704       Box0->Y    = Delta +    ( Box->DY / 2 ) - MiddleInDY;
1705       */
1706 
1707       Delta    = MiddleDY - ( Box->DY / 2 );
1708       Box0->Y  = Delta + ( Box->DY - Box0->DY ) / 2 ;
1709 
1710       /*
1711       MiddleInDY = Box0->DY - MiddleInDY;
1712       Delta      = MiddleDY - ( Box->DY / 2 ) + MiddleInDY - ( Box0->DY / 2 );
1713       Box0->Y    = Delta + ( Box->DY - Box0->DX ) / 2;
1714       */
1715 
1716       Y_cont2 += Delta;
1717 
1718       while ( IsSchBoxCluster( Box0 ) )
1719       {
1720         ScanBox = (ptype_list  *)Box0->SOURCE;
1721         BoxN    = (schbox_list *)ScanBox->DATA;
1722 
1723         Y_cont2 += BoxN->Y - ( ( Box0->DY - BoxN->DY ) / 2);
1724 
1725         Box0 = BoxN;
1726       }
1727     }
1728     else
1729     {
1730       if ( ( IsSchBoxTransparence( Box ) ) ||
1731            ( IsSchBoxClusterNet( Box )   ) )
1732       {
1733         Box->DX = 0;
1734       }
1735       else
1736       {
1737         if ( Box->DY <= SCP_BOX_MIN_DX )
1738         {
1739           Box->DX = SCP_BOX_MIN_DX;
1740         }
1741         else
1742         {
1743           Box->DX = Box->DY;
1744         }
1745       }
1746     }
1747 
1748     for ( Con  = Box->CON_IN;
1749           Con != (schcon_list *)0;
1750           Con  = Con->NEXT )
1751     {
1752       Con->X_REL = - SCP_BOX_CON_X;
1753       Con->Y_REL = Y_cont1;
1754 
1755       Y_cont1 = Y_cont1 - SCP_BOX_CON_STEP_Y;
1756 
1757     }
1758 
1759     for ( Con  = Box->CON_OUT;
1760           Con != (schcon_list *)0;
1761           Con  = Con->NEXT )
1762     {
1763       Con->X_REL = Box->DX + SCP_BOX_CON_X;
1764       Con->Y_REL = Y_cont2;
1765 
1766       Y_cont2 = Y_cont2 - SCP_BOX_CON_STEP_Y;
1767     }
1768   }
1769 
1770   return ( Figure );
1771 }
1772 
1773 /*------------------------------------------------------------\
1774 |                                                             |
1775 |                    Function  Loc Compact Wire               |
1776 |                                                             |
1777 \------------------------------------------------------------*/
1778 
loc_compactwirenet(SchNet)1779 static void loc_compactwirenet( SchNet )
1780 
1781   schnet_list *SchNet;
1782 {
1783   schwir_list  *ScanWire;
1784   schwir_list  *DelWire;
1785   schwir_list  *NextWire;
1786   schwir_list **PrevWire;
1787   long          Xmin;
1788   long          Xmax;
1789   long          Ymin;
1790   long          Ymax;
1791   short         ScanHor;
1792   short         NextHor;
1793   long          ScanX1;
1794   long          ScanX2;
1795   long          NextX1;
1796   long          NextX2;
1797   long          ScanY1;
1798   long          ScanY2;
1799   long          NextY1;
1800   long          NextY2;
1801 /*
1802 ** Delete point wire, and order others
1803 */
1804   PrevWire = &SchNet->WIRE;
1805   ScanWire = SchNet->WIRE;
1806 
1807   while ( ScanWire != (schwir_list *)0 )
1808   {
1809     if ( ( ScanWire->X == ScanWire->DX ) &&
1810          ( ScanWire->Y == ScanWire->DY ) )
1811     {
1812       *PrevWire = ScanWire->NEXT;
1813       DelWire   = ScanWire;
1814       ScanWire  = ScanWire->NEXT;
1815 
1816       freeschwir( DelWire );
1817     }
1818     else
1819     {
1820       if ( ScanWire->Y == ScanWire->DY )
1821       {
1822         Xmin = ScanWire->X;
1823         Xmax = ScanWire->DX;
1824 
1825         if ( Xmin > Xmax )
1826         {
1827           ScanWire->X  = Xmax;
1828           ScanWire->DX = Xmin;
1829         }
1830       }
1831       else
1832       {
1833         Ymin = ScanWire->Y;
1834         Ymax = ScanWire->DY;
1835 
1836         if ( Ymin > Ymax )
1837         {
1838           ScanWire->Y  = Ymax;
1839           ScanWire->DY = Ymin;
1840         }
1841       }
1842 
1843       PrevWire = &ScanWire->NEXT;
1844       ScanWire = ScanWire->NEXT;
1845     }
1846   }
1847 /*
1848 ** Build big wire !
1849 */
1850   PrevWire = &SchNet->WIRE;
1851   ScanWire = SchNet->WIRE;
1852 
1853   while ( ScanWire != (schwir_list *)0 )
1854   {
1855     if ( ScanWire->Y == ScanWire->DY ) ScanHor = 1;
1856     else                               ScanHor = 0;
1857 
1858     for ( NextWire  = ScanWire->NEXT;
1859           NextWire != (schwir_list *)0;
1860           NextWire  = NextWire->NEXT )
1861     {
1862       if ( NextWire->Y == NextWire->DY ) NextHor = 1;
1863       else                               NextHor = 0;
1864 
1865       if ( ScanHor == NextHor )
1866       {
1867 /*
1868 ** Horizontal wires
1869 */
1870         if ( ScanHor == 1 )
1871         {
1872           if ( ScanWire->Y == NextWire->Y )
1873           {
1874             ScanX1 = ScanWire->X;
1875             ScanX2 = ScanWire->DX;
1876             NextX1 = NextWire->X;
1877             NextX2 = NextWire->DX;
1878 /*
1879 ** Intersection between to horizontal wires
1880 */
1881             if ( ( NextX1 <= ScanX2 ) &&
1882                  ( NextX2 >= ScanX1 ) )
1883             {
1884               if ( ScanX1 < NextX1 ) Xmin = ScanX1;
1885               else                   Xmin = NextX1;
1886 
1887               if ( ScanX2 > NextX2 ) Xmax = ScanX2;
1888               else                   Xmax = NextX2;
1889 
1890               NextWire->X  = Xmin;
1891               NextWire->DX = Xmax;
1892 
1893               break;
1894             }
1895           }
1896         }
1897         else
1898 /*
1899 ** Vertical wires
1900 */
1901         {
1902           if ( ScanWire->X == NextWire->X )
1903           {
1904             ScanY1 = ScanWire->Y;
1905             ScanY2 = ScanWire->DY;
1906             NextY1 = NextWire->Y;
1907             NextY2 = NextWire->DY;
1908 /*
1909 ** Intersection between to vertical wires
1910 */
1911             if ( ( NextY1 <= ScanY2 ) &&
1912                  ( NextY2 >= ScanY1 ) )
1913             {
1914               if ( ScanY1 < NextY1 ) Ymin = ScanY1;
1915               else                   Ymin = NextY1;
1916 
1917               if ( ScanY2 > NextY2 ) Ymax = ScanY2;
1918               else                   Ymax = NextY2;
1919 
1920               NextWire->Y  = Ymin;
1921               NextWire->DY = Ymax;
1922 
1923               break;
1924             }
1925           }
1926         }
1927       }
1928     }
1929 
1930     if ( NextWire != (schwir_list *)0 )
1931     {
1932       *PrevWire = ScanWire->NEXT;
1933       DelWire   = ScanWire;
1934       ScanWire  = ScanWire->NEXT;
1935 
1936       freeschwir( DelWire );
1937     }
1938     else
1939     {
1940       PrevWire = &ScanWire->NEXT;
1941       ScanWire = ScanWire->NEXT;
1942     }
1943   }
1944 }
1945 
1946 /*------------------------------------------------------------\
1947 |                                                             |
1948 |                    Function  Loc Clean All                  |
1949 |                                                             |
1950 \------------------------------------------------------------*/
1951 
loc_clean_all(Figure)1952 static void loc_clean_all( Figure )
1953 
1954   schfig_list *Figure;
1955 {
1956   schbox_list *ScanBox;
1957   schnet_list *ScanNet;
1958 
1959   for ( ScanBox  = Figure->BOX;
1960         ScanBox != (schbox_list *)0;
1961         ScanBox  = ScanBox->NEXT )
1962   {
1963     if ( (   IsSchBoxCluster( ScanBox   ) ) &&
1964          ( ! IsSchBoxClustered( ScanBox ) ) )
1965     {
1966       loc_destroycluster( Figure, ScanBox );
1967     }
1968   }
1969 
1970   for ( ScanBox  = Figure->BOX;
1971         ScanBox != (schbox_list *)0;
1972         ScanBox  = ScanBox->NEXT )
1973   {
1974     if ( IsSchBoxTransparence( ScanBox ) )
1975     {
1976       loc_destroytransparence( Figure, ScanBox );
1977     }
1978   }
1979 
1980   for ( ScanBox  = Figure->BOX;
1981         ScanBox != (schbox_list *)0;
1982         ScanBox  = ScanBox->NEXT )
1983   {
1984     if ( IsSchBoxClusterNet( ScanBox ) )
1985     {
1986       loc_destroyclusternet( Figure, ScanBox );
1987     }
1988   }
1989 
1990   for ( ScanNet  = Figure->NET;
1991         ScanNet != (schnet_list *)0;
1992         ScanNet  = ScanNet->NEXT )
1993   {
1994     loc_compactwirenet( ScanNet );
1995   }
1996 
1997   delscpcol();
1998 }
1999 
2000 /*------------------------------------------------------------\
2001 |                                                             |
2002 |                         Function  Build                     |
2003 |                                                             |
2004 \------------------------------------------------------------*/
2005 
placerouteschfig(SchFigure)2006 void placerouteschfig( SchFigure )
2007 
2008   schfig_list *SchFigure;
2009 {
2010 # ifdef DEBUG
2011     fprintf(stdout, "--- Detection des clusters ---\n");
2012     fflush(stdout);
2013 # endif
2014     loc_buildcluster(SchFigure);
2015 # ifdef DEBUG
2016     fprintf(stdout, "----- Placement  initial -----\n");
2017     fflush(stdout);
2018 # endif
2019     loc_placement_initial(SchFigure);
2020 # ifdef DEBUG
2021     fprintf(stdout, "--- Fabrication des boites ---\n");
2022     fflush(stdout);
2023     fflush(stdout);
2024 # endif
2025     loc_buildbox(SchFigure);
2026 # ifdef DEBUG
2027     fprintf(stdout, "---------  Placement ---------\n");
2028     fflush(stdout);
2029     fflush(stdout);
2030 # endif
2031     loc_buildplace(SchFigure);
2032 # ifdef DEBUG
2033     fprintf(stdout, "----------  Routage ----------\n");
2034     fflush(stdout);
2035     fflush(stdout);
2036 # endif
2037     loc_route(SchFigure);
2038 # ifdef DEBUG
2039     fprintf(stdout, "---------- Nettoyage  --------\n");
2040     fflush(stdout);
2041 # endif
2042     loc_clean_all(SchFigure);
2043 }
2044