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