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 General Public |
11 | 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 |                                                             |
30 | Tool    :                   GRAAL                           |
31 |                                                             |
32 | File    :                   Equi.c                          |
33 |                                                             |
34 | Author  :                Jacomme Ludovic                    |
35 |                                                             |
36 | Date    :                  28.03.95                         |
37 |                                                             |
38 \------------------------------------------------------------*/
39 /*------------------------------------------------------------\
40 |                                                             |
41 |                         Include Files                       |
42 |                                                             |
43 \------------------------------------------------------------*/
44 
45 # include <stdio.h>
46 # include <string.h>
47 # include "mut.h"
48 # include "mph.h"
49 # include "rds.h"
50 # include "rpr.h"
51 # include "rfm.h"
52 # include "GRM.h"
53 # include "GSB.h"
54 # include "GRM_equi.h"
55 # include "GRM_window.h"
56 
57 /*------------------------------------------------------------\
58 |                                                             |
59 |                           Constants                         |
60 |                                                             |
61 \------------------------------------------------------------*/
62 /*------------------------------------------------------------\
63 |                                                             |
64 |                            Types                            |
65 |                                                             |
66 \------------------------------------------------------------*/
67 /*------------------------------------------------------------\
68 |                                                             |
69 |                          Variables                          |
70 |                                                             |
71 \------------------------------------------------------------*/
72 
73   rdsrec_list *GraalHeadEqui = (rdsrec_list *)NULL;
74 
75   static char GraalReferenceBuffer[ GRAAL_REFERENCE_BUFFER_SIZE ];
76 
77 /*------------------------------------------------------------\
78 |                                                             |
79 |                          Functions                          |
80 |                                                             |
81 \------------------------------------------------------------*/
82 /*------------------------------------------------------------\
83 |                                                             |
84 |                         GraalCutCx                          |
85 |                                                             |
86 \------------------------------------------------------------*/
87 
GraalCutCx(Rec,X1,Y1,X2,Y2)88 rdsrec_list *GraalCutCx( Rec, X1, Y1, X2, Y2  )
89 
90   rdsrec_list *Rec;
91   long         X1;
92   long         Y1;
93   long         X2;
94   long         Y2;
95 {
96   void        *Pointer;
97   phseg_list  *Segment;
98   rdsrec_list *Diff;
99   rdsrec_list *Save;
100   rdsrec_list *ScanRec;
101   graalrecwin *RecWin;
102   graalrecwin *ScanRecWin;
103   graalrecwin  StaticRecWin;
104   graalwin    *ScanWin;
105   graalwinrec *ScanWinRec;
106   long        *Table;
107   long        *LineTable;
108   long         Xvia;
109   long         Yvia;
110   char         Index;
111   char         Mask;
112   char         MbkLayer;
113   char         DiffLayer;
114   char         GateLayer;
115   char         CXType;
116 
117   rdsbegin();
118 
119   Pointer = GRAAL_MBK( Rec );
120   Xvia    = ((phvia_list *)Pointer)->XVIA;
121   Yvia    = ((phvia_list *)Pointer)->YVIA;
122   CXType  = ((phvia_list *)Pointer)->TYPE;
123 
124   MbkLayer  = GRAAL_CUT_C_X_LIST[ (int)CXType ];
125   GateLayer = GET_LYNX_TRANSISTOR_GATE_LAYER( MbkLayer );
126   DiffLayer = GET_LYNX_TRANSISTOR_DIFF_LAYER( MbkLayer );
127 
128   if ( GetRdsLayer( Rec ) != DiffLayer )
129   {
130     rdsend();
131     return( Rec );
132   }
133 
134   Table = GRAAL_CUT_C_X_ARRAY[ (int)MbkLayer ];
135   Mask  = 0;
136   Save  = Rec;
137 
138   if ( IsGraalOneWindow ( Rec ) )
139   {
140     StaticRecWin.NEXT   = (graalrecwin *)NULL;
141     StaticRecWin.WINDOW = (graalwin *)GRAAL_WINDOW( Rec );
142     RecWin              = &StaticRecWin;
143   }
144   else
145   {
146     RecWin = GRAAL_WINDOW( Rec );
147   }
148 
149   for ( ScanRecWin  = RecWin ;
150         ScanRecWin != (graalrecwin *) NULL ;
151         ScanRecWin  = ScanRecWin->NEXT )
152   {
153     ScanWin = ScanRecWin->WINDOW;
154 
155     for ( ScanWinRec  = ScanWin->LAYERTAB[ (int)GateLayer ];
156           ScanWinRec != (graalwinrec *)NULL;
157           ScanWinRec  = ScanWinRec->NEXT )
158     {
159       for ( Index = 0; Index < GRAAL_MAX_REC; Index++ )
160       {
161         ScanRec = ScanWinRec->RECTAB[ (int)Index ];
162 
163         if ( ( ScanRec != (rdsrec_list *)NULL    ) &&
164              ( ! IsGraalDeleted( ScanRec )       ) &&
165              (   IsRdsFigRec( ScanRec )          ) &&
166              (   IsRdsSegment( ScanRec )         ) )
167         {
168           Segment = (phseg_list *)GRAAL_MBK( ScanRec );
169 
170           if ( Segment->LAYER == MbkLayer )
171           {
172             if ( ( Segment->TYPE == UP   ) ||
173                  ( Segment->TYPE == DOWN ) )
174             {
175               if ( Segment->X1 == Xvia )
176               {
177                 if ( Segment->Y1 == Yvia ) Mask |= GRAAL_NORTH_MASK;
178                 else
179                 if ( Segment->Y2 == Yvia ) Mask |= GRAAL_SOUTH_MASK;
180               }
181             }
182             else
183             {
184               if ( Segment->Y1 == Yvia )
185               {
186                 if ( Segment->X1 == Xvia ) Mask |= GRAAL_EAST_MASK;
187                 else
188                 if ( Segment->X2 == Xvia ) Mask |= GRAAL_WEST_MASK;
189               }
190             }
191           }
192         }
193       }
194     }
195   }
196 
197   if ( Mask != 0 )
198   {
199     Diff = (rdsrec_list *)NULL;
200 
201     LineTable = &Table[ Mask << 4 ];
202 
203     for ( Index = 0; Index < 16; Index = Index + 4 )
204     {
205       if ( LineTable[ (int)Index ]  == -1 ) break;
206 
207       Diff = addrdsfigrec( GraalFigureRds,
208                            NULL, DiffLayer,
209                            Rec->X + LineTable[ Index + 0 ],
210                            Rec->Y + LineTable[ Index + 1 ],
211                            LineTable[ Index + 2 ],
212                            LineTable[ Index + 3 ] );
213 
214       GRAAL_PREVIOUS( Diff ) =
215 
216         &(GraalFigureRds->LAYERTAB[ (int)DiffLayer ]);
217 
218       if ( Diff->NEXT != (rdsrec_list *)NULL )
219       {
220         GRAAL_PREVIOUS( Diff->NEXT ) = &Diff->NEXT;
221       }
222 
223       GRAAL_MBK( Diff ) = GRAAL_MBK( Rec );
224 
225       Diff->USER = Rec->USER;
226       Rec->USER  = (void *)Diff;
227 
228       SetGraalCut( Diff );
229       GraalInsertRectangle( Diff );
230 
231       if ( ( ( Diff->X            ) <= X2 ) &&
232            ( ( Diff->Y            ) <= Y2 ) &&
233            ( ( Diff->X + Diff->DX ) >= X1 ) &&
234            ( ( Diff->Y + Diff->DY ) >= Y1 ) )
235 
236       {
237         Save = Diff;
238       }
239     }
240 
241     if ( Save != Rec ) SetGraalInvisible( Rec );
242   }
243 
244   rdsend();
245   return( Save );
246 }
247 
248 /*------------------------------------------------------------\
249 |                                                             |
250 |                        GraalExtractEqui                     |
251 |                                                             |
252 \------------------------------------------------------------*/
253 
GraalExtractEqui(Rec)254 void GraalExtractEqui( Rec )
255 
256   rdsrec_list *Rec;
257 {
258   rdsrec_list *LastRec;
259   rdsrec_list *ScanRec;
260   rdsrec_list *ScanInsRec;
261   rdsins_list *ScanIns;
262   graalrecwin *RecWin;
263   graalrecwin *ScanRecWin;
264   graalrecwin  StaticRecWin;
265   graalwin    *ScanWin;
266   graalwinrec *ScanWinRec;
267   char        *RefName;
268   char        *ScanRecName;
269   char        *ScanInsRecName;
270   void        *Pointer;
271   int          Index;
272   int          LayerIns;
273   int          LayerRec;
274   int          Layer;
275   int          Counter;
276   long         X1;
277   long         X2;
278   long         Y1;
279   long         Y2;
280 
281   rdsbegin();
282 
283   if ( GraalHeadEqui != (rdsrec_list *)NULL )
284   {
285     GraalDelEqui();
286   }
287 
288   StaticRecWin.NEXT = (graalrecwin *)NULL;
289 
290   GraalHeadEqui = Rec;
291   SetGraalTreated( Rec );
292 
293   ScanRec = (rdsrec_list *)Rec->USER;
294   LastRec = Rec;
295 
296   while ( ScanRec != Rec )
297   {
298     SetGraalTreated( ScanRec );
299 
300     GRAAL_EQUI( LastRec ) = ScanRec;
301     LastRec               = ScanRec;
302     ScanRec               = (rdsrec_list *)ScanRec->USER;
303   }
304 
305   Rec = GraalHeadEqui;
306 
307   do
308   {
309     X1 = Rec->X;
310     Y1 = Rec->Y;
311     X2 = Rec->DX + X1;
312     Y2 = Rec->DY + Y1;
313 
314     if ( IsGraalOneWindow ( Rec ) )
315     {
316       StaticRecWin.WINDOW = (graalwin *)GRAAL_WINDOW( Rec );
317       RecWin              = &StaticRecWin;
318     }
319     else
320     {
321       RecWin = GRAAL_WINDOW( Rec );
322     }
323 
324     LayerRec = GetRdsLayer ( Rec );
325 
326     for ( ScanRecWin  = RecWin ;
327           ScanRecWin != (graalrecwin *) NULL ;
328           ScanRecWin  = ScanRecWin->NEXT )
329     {
330       ScanWin = ScanRecWin->WINDOW;
331 
332       Index = 0;
333 
334       while ( ( Layer = GET_LYNX_GRAPH_LAYER ( LayerRec, Index ) ) != RDS_LYNX_GRAPH_EMPTY )
335       {
336         for ( ScanWinRec  = ScanWin->LAYERTAB[ Layer ];
337               ScanWinRec != (graalwinrec *)NULL;
338               ScanWinRec  = ScanWinRec->NEXT )
339         {
340           for ( Counter = 0; Counter < GRAAL_MAX_REC; Counter++ )
341           {
342             ScanRec = ScanWinRec->RECTAB[ Counter ];
343 
344             if ( ( ScanRec != (rdsrec_list *)NULL     ) &&
345                  ( ! IsGraalDeleted( ScanRec )        ) &&
346                  ( ! IsGraalTreated( ScanRec )        ) &&
347                  ( ! IsGraalInvisible( ScanRec )      ) &&
348                  ( ( ScanRec->X               ) <= X2 ) &&
349                  ( ( ScanRec->Y               ) <= Y2 ) &&
350                  ( ( ScanRec->X + ScanRec->DX ) >= X1 ) &&
351                  ( ( ScanRec->Y + ScanRec->DY ) >= Y1 ) )
352             {
353               if ( IsRdsFigRec( ScanRec ) )
354               {
355                 if ( ( IsRdsVia( ScanRec           ) ) &&
356                      (   IsRdsFigRec( ScanRec      ) ) &&
357                      ( ! IsGraalInvisible( ScanRec ) ) &&
358                      ( ! IsGraalCut( ScanRec       ) ) )
359                 {
360                   Pointer = GRAAL_MBK( ScanRec );
361 
362                   if ( GRAAL_CUT_C_X_LIST[ (int)((phvia_list *)Pointer)->TYPE ] < MBK_MAX_LAYER )
363                   {
364                     ScanRec = GraalCutCx( ScanRec, X1, Y1, X2, Y2 );
365                   }
366                 }
367 
368                 SetGraalTreated( ScanRec );
369 
370                 GRAAL_EQUI( LastRec ) = ScanRec;
371                 LastRec               = ScanRec;
372               }
373               else
374               if ( ( IsRdsConInter( ScanRec ) ) ||
375                    ( IsRdsRefCon( ScanRec   ) ) )
376               {
377                 SetGraalTreated( ScanRec );
378 
379                 if ( ( IsRdsRefCon( ScanRec )        ) &&
380                      ( ScanRec->NAME != (char *)NULL ) )
381                 {
382                   strcpy( GraalReferenceBuffer, ScanRec->NAME );
383 
384                   RefName = strrchr( GraalReferenceBuffer, '_' );
385 
386                   if ( RefName != (char *)NULL )
387                   {
388                     *RefName = '\0';
389                   }
390 
391                   ScanRecName = namealloc( GraalReferenceBuffer );
392                 }
393                 else
394                 {
395                   ScanRecName = ScanRec->NAME;
396                 }
397 
398                 GRAAL_EQUI( LastRec ) = ScanRec;
399                 LastRec               = ScanRec;
400 
401                 ScanIns = (rdsins_list *)GRAAL_PREVIOUS( ScanRec );
402 
403                 if ( ! IsGraalDeleted( ScanIns->LAYERTAB[ RDS_ABOX ] ) )
404                 {
405                   for ( LayerIns = 0 ; LayerIns < RDS_MAX_LAYER ; LayerIns ++ )
406                   {
407                     for ( ScanInsRec  = ScanIns->LAYERTAB[ LayerIns ];
408                           ScanInsRec != (rdsrec_list *)NULL;
409                           ScanInsRec  = ScanInsRec->NEXT )
410                     {
411                       if ( ! IsGraalTreated( ScanInsRec ) )
412                       {
413                         if ( ( IsRdsRefCon( ScanInsRec )        ) &&
414                              ( ScanInsRec->NAME != (char *)NULL ) )
415                         {
416                           strcpy( GraalReferenceBuffer, ScanInsRec->NAME );
417 
418                           RefName = strrchr( GraalReferenceBuffer, '_' );
419 
420                           if ( RefName != (char *)NULL )
421                           {
422                             *RefName = '\0';
423                           }
424 
425                           ScanInsRecName = namealloc( GraalReferenceBuffer );
426                         }
427                         else
428                         {
429                           ScanInsRecName = ScanInsRec->NAME;
430                         }
431 
432                         if ( ( ( IsRdsConInter( ScanInsRec ) ) ||
433                                ( IsRdsRefCon( ScanInsRec )   ) ) &&
434                              ( ScanRecName == ScanInsRecName   ) )
435                         {
436                           SetGraalTreated( ScanInsRec );
437 
438                           GRAAL_EQUI( LastRec ) = ScanInsRec;
439                           LastRec               = ScanInsRec;
440                         }
441                       }
442                     }
443                   }
444                 }
445               }
446             }
447           }
448         }
449 
450         Index = Index + 1;
451       }
452     }
453 
454     Rec = GRAAL_EQUI( Rec );
455   }
456   while ( Rec != (rdsrec_list *)NULL );
457 
458   rdsend();
459 }
460 
461 /*------------------------------------------------------------\
462 |                                                             |
463 |                        GraalDelEqui                         |
464 |                                                             |
465 \------------------------------------------------------------*/
466 
GraalDelEqui()467 void GraalDelEqui()
468 
469 {
470   rdsrec_list  *Rec;
471   rdsrec_list  *ScanRec;
472   rdsrec_list  *DelEqui;
473   rdsrec_list  *DelRec;
474   rdsrec_list  *FirstRec;
475   void        **Previous;
476 
477   rdsbegin();
478 
479   Rec = GraalHeadEqui;
480 
481   while ( Rec != (rdsrec_list *)NULL )
482   {
483     ClearGraalTreated( Rec );
484 
485     DelEqui = Rec;
486     Rec     = GRAAL_EQUI( Rec );
487 
488     GRAAL_EQUI( DelEqui ) = (rdsrec_list *)NULL;
489 
490     if ( IsGraalCut( DelEqui  ) )
491     {
492       ScanRec  = DelEqui;
493       Previous = &ScanRec->USER;
494       FirstRec = ScanRec;
495       ScanRec  = (rdsrec_list *)(ScanRec->USER);
496 
497       do
498       {
499         if ( ( IsGraalCut( ScanRec )                        ) &&
500              ( GRAAL_EQUI( ScanRec ) == (rdsrec_list *)NULL ) )
501         {
502           *Previous = ScanRec->USER;
503           DelRec    = ScanRec;
504           ScanRec   = (rdsrec_list *)(ScanRec->USER);
505 
506           *(GRAAL_PREVIOUS( DelRec )) = DelRec->NEXT;
507 
508           if ( DelRec->NEXT != (rdsrec_list *)NULL )
509           {
510             GRAAL_PREVIOUS( DelRec->NEXT ) = GRAAL_PREVIOUS( DelRec );
511           }
512 
513           GraalEraseRectangle( DelRec );
514 
515           freerdsrec( DelRec, GRAAL_SIZE );
516         }
517         else
518         {
519           ClearGraalInvisible( ScanRec );
520 
521           Previous = &(ScanRec->USER);
522           ScanRec  = (rdsrec_list *)(ScanRec->USER);
523         }
524       }
525       while ( ScanRec != FirstRec );
526 
527       if ( ( IsGraalCut( ScanRec )                        ) &&
528            ( GRAAL_EQUI( ScanRec ) == (rdsrec_list *)NULL ) )
529       {
530         *Previous = ScanRec->USER;
531         DelRec    = ScanRec;
532         ScanRec   = (rdsrec_list *)(ScanRec->USER);
533 
534         *(GRAAL_PREVIOUS( DelRec )) = DelRec->NEXT;
535 
536         if ( DelRec->NEXT != (rdsrec_list *)NULL )
537         {
538           GRAAL_PREVIOUS( DelRec->NEXT ) = GRAAL_PREVIOUS( DelRec );
539         }
540 
541         GraalEraseRectangle( DelRec );
542 
543         freerdsrec( DelRec, GRAAL_SIZE );
544       }
545       else
546       {
547         ClearGraalInvisible( ScanRec );
548       }
549     }
550   }
551 
552   GraalHeadEqui = (rdsrec_list *)NULL;
553 
554   rdsend();
555 }
556