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    :                     VASY                          |
31 |                                                             |
32 | File    :                  vasy_simul.c                     |
33 |                                                             |
34 | Authors :                Jacomme Ludovic                    |
35 |                                                             |
36 | Date    :                   28.08.97                        |
37 |                                                             |
38 \------------------------------------------------------------*/
39 /*------------------------------------------------------------\
40 |                                                             |
41 |                         Include Files                       |
42 |                                                             |
43 \------------------------------------------------------------*/
44 
45 # include <stdio.h>
46 # include <stdlib.h>
47 # include <string.h>
48 
49 # include "mut.h"
50 # include "aut.h"
51 # include "vex.h"
52 # include "vpn.h"
53 # include "vtl.h"
54 
55 # include "vasy_error.h"
56 # include "vasy_debug.h"
57 # include "vasy_simul.h"
58 
59 /*------------------------------------------------------------\
60 |                                                             |
61 |                           Constants                         |
62 |                                                             |
63 \------------------------------------------------------------*/
64 /*------------------------------------------------------------\
65 |                                                             |
66 |                            Types                            |
67 |                                                             |
68 \------------------------------------------------------------*/
69 /*------------------------------------------------------------\
70 |                                                             |
71 |                          Variables                          |
72 |                                                             |
73 \------------------------------------------------------------*/
74 /*------------------------------------------------------------\
75 |                                                             |
76 |                      Private variables                      |
77 |                                                             |
78 \------------------------------------------------------------*/
79 
80   static vpnfig_list  *VasyFigure     = (vpnfig_list  *)0;
81   static vpnline_list *VasyVpnLine    = (vpnline_list *)0;
82 
83   static vasysimul *VasySimulateVex();
84 
85   static vasysimul *VasySimulateVexConcat();
86   static vasysimul *VasySimulateVexLogic();
87   static vasysimul *VasySimulateVexEvent();
88   static vasysimul *VasySimulateVexNeg();
89   static vasysimul *VasySimulateVexAbs();
90   static vasysimul *VasySimulateVexSum();
91   static vasysimul *VasySimulateVexEqual();
92   static vasysimul *VasySimulateVexCompare();
93   static vasysimul *VasySimulateVexSlice();
94   static vasysimul *VasySimulateVexDriver();
95 
96   static vasysimul *(*VasySimulOperFunc[ VEX_MAX_OPERATOR ])() =
97   {
98      VasySimulateVexConcat,     /* VEX_CONCAT    */
99      VasySimulateVexLogic,      /* VEX_NOT       */
100      VasySimulateVexNeg,        /* VEX_NEG       */
101      VasySimulateVexEvent,      /* VEX_EVENT     */
102      VasySimulateVexLogic,      /* VEX_OR        */
103      VasySimulateVexLogic,      /* VEX_AND       */
104      VasySimulateVexLogic,      /* VEX_XOR       */
105      VasySimulateVexLogic,      /* VEX_NOR       */
106      VasySimulateVexLogic,      /* VEX_NAND      */
107      VasySimulateVexLogic,      /* VEX_NXOR      */
108      VasySimulateVexEqual,      /* VEX_EQ        */
109      VasySimulateVexEqual,      /* VEX_NE        */
110      VasySimulateVexCompare,    /* VEX_LT        */
111      VasySimulateVexCompare,    /* VEX_LE        */
112      VasySimulateVexCompare,    /* VEX_GT        */
113      VasySimulateVexCompare,    /* VEX_GE        */
114      VasySimulateVexSum,        /* VEX_ADD       */
115      VasySimulateVexSum,        /* VEX_SUB       */
116      NULL,                      /* VEX_MUL       */
117      NULL,                      /* VEX_DIV       */
118      NULL,                      /* VEX_EXP       */
119      NULL,                      /* VEX_MOD       */
120      NULL,                      /* VEX_REM       */
121      VasySimulateVexSlice,      /* VEX_TO        */
122      VasySimulateVexSlice,      /* VEX_DOWNTO    */
123      VasySimulateVexSlice,      /* VEX_INDEX     */
124      NULL,                      /* VEX_LEFT      */
125      NULL,                      /* VEX_RIGHT     */
126      NULL,                      /* VEX_LOW       */
127      NULL,                      /* VEX_HIGH      */
128      NULL,                      /* VEX_LENGTH    */
129      NULL,                      /* VEX_RANGE     */
130      NULL,                      /* VEX_REV_RANGE */
131      VasySimulateVexDriver,     /* VEX_DRIVER    */
132      VasySimulateVexLogic,      /* VEX_IFT       */
133      NULL,                      /* VEX_ARRAY     */
134      NULL,                      /* VEX_INDEX_N   */
135      NULL,                      /* VEX_OTHERS    */
136      NULL,                      /* VEX_NUM_BIT   */
137      VasySimulateVexAbs,        /* VEX_ABS       */
138      NULL,                      /* AF            */
139      NULL,                      /* AG            */
140      NULL,                      /* AX            */
141      NULL,                      /* AU            */
142      NULL,                      /* EF            */
143      NULL,                      /* EG            */
144      NULL,                      /* EX            */
145      NULL,                      /* EU            */
146      NULL,                      /* EQUIV         */
147      NULL                       /* IMPLY         */
148   };
149 
150   static char VasyTruthTableAnd[ VEX_MAX_ID ][ VEX_MAX_ID ] =
151   {
152     /*  --------------------------------------------------
153     **  |  U    X    0    1    Z    W    L    H    -
154     **  --------------------------------------------------
155     */
156         {  0 ,  0 ,  2 ,  0 ,  0 ,  0 ,  2 ,  0 ,  0  },  /* u */
157         {  0 ,  1 ,  2 ,  1 ,  1 ,  1 ,  2 ,  1 ,  1  },  /* x */
158         {  2 ,  2 ,  2 ,  2 ,  2 ,  2 ,  2 ,  2 ,  2  },  /* 0 */
159         {  0 ,  1 ,  2 ,  3 ,  1 ,  1 ,  2 ,  3 ,  1  },  /* 1 */
160         {  0 ,  1 ,  2 ,  1 ,  1 ,  1 ,  2 ,  1 ,  1  },  /* z */
161         {  0 ,  1 ,  2 ,  1 ,  1 ,  1 ,  2 ,  1 ,  1  },  /* w */
162         {  2 ,  2 ,  2 ,  2 ,  2 ,  2 ,  2 ,  2 ,  2  },  /* l */
163         {  0 ,  1 ,  2 ,  3 ,  1 ,  1 ,  2 ,  3 ,  1  },  /* h */
164         {  0 ,  1 ,  2 ,  1 ,  1 ,  1 ,  2 ,  1 ,  1  }   /* - */
165   };
166 
167   static char VasyTruthTableOr[ VEX_MAX_ID ][ VEX_MAX_ID ] =
168   {
169     /*  ----------------------------------------------------
170     **  |  u    x    0    1    z    w    l    h    -
171     **  ----------------------------------------------------
172     */
173         {  0 ,  0 ,  0 ,  3 ,  0 ,  0 ,  0 ,  3 ,  0  },  /* u */
174         {  0 ,  1 ,  1 ,  3 ,  1 ,  1 ,  1 ,  3 ,  1  },  /* x */
175         {  0 ,  1 ,  2 ,  3 ,  1 ,  1 ,  2 ,  3 ,  1  },  /* 0 */
176         {  3 ,  3 ,  3 ,  3 ,  3 ,  3 ,  3 ,  3 ,  3  },  /* 1 */
177         {  0 ,  1 ,  1 ,  3 ,  1 ,  1 ,  1 ,  3 ,  1  },  /* z */
178         {  0 ,  1 ,  1 ,  3 ,  1 ,  1 ,  1 ,  3 ,  1  },  /* w */
179         {  0 ,  1 ,  2 ,  3 ,  1 ,  1 ,  2 ,  3 ,  1  },  /* l */
180         {  3 ,  3 ,  3 ,  3 ,  3 ,  3 ,  3 ,  3 ,  3  },  /* h */
181         {  0 ,  1 ,  1 ,  3 ,  1 ,  1 ,  1 ,  3 ,  1  }   /* - */
182   };
183 
184   static char VasyTruthTableXor[ VEX_MAX_ID ][ VEX_MAX_ID ] =
185   {
186     /*  ----------------------------------------------------
187     **  |  u    x    0    1    z    w    l    h    -
188     **  ----------------------------------------------------
189     */
190         {  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0  },  /* u */
191         {  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1  },  /* x */
192         {  0 ,  1 ,  2 ,  3 ,  1 ,  1 ,  2 ,  3 ,  1  },  /* 0 */
193         {  0 ,  1 ,  3 ,  2 ,  1 ,  1 ,  3 ,  2 ,  1  },  /* 1 */
194         {  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1  },  /* z */
195         {  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1  },  /* w */
196         {  0 ,  1 ,  2 ,  3 ,  1 ,  1 ,  2 ,  3 ,  1  },  /* l */
197         {  0 ,  1 ,  3 ,  2 ,  1 ,  1 ,  3 ,  2 ,  1  },  /* h */
198         {  0 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1 ,  1  }   /* - */
199   };
200 
201   static char VasyTruthTableNot[ VEX_MAX_ID ] =
202   {
203     /*  ----------------------------------------------------
204     **  |  u    x    0    1    z    w    l    h    -
205     **  ----------------------------------------------------
206     */
207             0 ,  1 ,  3 ,  2 ,  1 ,  1 ,  3 ,  2 ,  1
208   };
209 
210 /*------------------------------------------------------------\
211 |                                                             |
212 |                          Functions                          |
213 |                                                             |
214 \------------------------------------------------------------*/
215 /*------------------------------------------------------------\
216 |                                                             |
217 |                     VasySimulateViewSimul                   |
218 |                                                             |
219 \------------------------------------------------------------*/
220 
VasySimulateViewSimul(ScanSimul)221 static void VasySimulateViewSimul( ScanSimul )
222 
223   vasysimul *ScanSimul;
224 {
225   char    *Value;
226   int      Position;
227   int      Width;
228 
229   VasyPrintf( stdout, "    --> VasySimulateViewSimul %d %d\n",
230              ScanSimul->WIDTH, ScanSimul->SIGNED );
231 
232   Value   = ScanSimul->VALUE;
233   Width   = ScanSimul->WIDTH;
234 
235   for ( Position = 0; Position < Width; Position++ )
236   {
237     VasyPrintf( stdout, "    +++ Simul[ %d ] > %c\n",
238                Position, VEX_LITERAL_BY_ID[ (int)Value[ Position ] ] );
239   }
240 
241   VasyPrintf( stdout, "    <-- VasySimulateViewSimul\n" );
242 }
243 
244 /*------------------------------------------------------------\
245 |                                                             |
246 |                      VasySimulateAddSimul                   |
247 |                                                             |
248 \------------------------------------------------------------*/
249 
VasySimulateAddSimul(Width,Signed)250 static vasysimul *VasySimulateAddSimul( Width, Signed )
251 
252   short Width;
253   short Signed;
254 {
255   vasysimul *NewSimul;
256 
257   NewSimul = (vasysimul *)autallocheap( sizeof( vasysimul ) );
258 
259   NewSimul->VALUE  = autallocheap( Width );
260   NewSimul->WIDTH  = Width;
261   NewSimul->SIGNED = Signed;
262 
263   return( NewSimul );
264 }
265 
266 /*------------------------------------------------------------\
267 |                                                             |
268 |                      VasySimulateDelSimul                   |
269 |                                                             |
270 \------------------------------------------------------------*/
271 
VasySimulateDelSimul(DelSimul)272 void VasySimulateDelSimul( DelSimul )
273 
274   vasysimul *DelSimul;
275 {
276   autfreeheap( DelSimul->VALUE, DelSimul->WIDTH );
277   autfreeheap( DelSimul, sizeof( vasysimul ) );
278 }
279 
280 /*------------------------------------------------------------\
281 |                                                             |
282 |                      VasySimulateSignSimul                  |
283 |                                                             |
284 \------------------------------------------------------------*/
285 
VasySimulateSignSimul(Simul)286 static vasysimul *VasySimulateSignSimul( Simul )
287 
288   vasysimul *Simul;
289 {
290   vasysimul *NewSimul;
291   char     *NewValue;
292   char     *Value;
293   int       Position;
294 
295   Value = Simul->VALUE;
296 
297   if ( ! Simul->SIGNED )
298   {
299     if ( IsVasyDebugLevel2() )
300     {
301       VasyPrintf( stdout, "  --> VasySimulateSignSimul\n" );
302       VasySimulateViewSimul( Simul );
303     }
304 
305     if ( Value[ 0 ] == VEX_ONE_ID )
306     {
307       NewSimul = VasySimulateAddSimul( Simul->WIDTH + 1, 1 );
308       NewValue = NewSimul->VALUE;
309 
310       NewValue[ 0 ] = VEX_ZERO_ID;
311 
312       for ( Position = 0; Position < Simul->WIDTH; Position++ )
313       {
314         NewValue[ Position + 1 ] = Value[ Position ];
315       }
316 
317       VasySimulateDelSimul( Simul );
318       Simul = NewSimul;
319     }
320 
321     Simul->SIGNED = 1;
322 
323     if ( IsVasyDebugLevel2() )
324     {
325       VasySimulateViewSimul( Simul );
326       VasyPrintf( stdout, "  <-- VasySimulateSignSimul\n" );
327     }
328   }
329 
330   return( Simul );
331 }
332 
333 /*------------------------------------------------------------\
334 |                                                             |
335 |                    VasySimulateIncWidthSimul                |
336 |                                                             |
337 \------------------------------------------------------------*/
338 
VasySimulateCarryOutSimul(Simul,CarryOut)339 static vasysimul *VasySimulateCarryOutSimul( Simul, CarryOut )
340 
341   vasysimul *Simul;
342   char      CarryOut;
343 {
344   vasysimul *NewSimul;
345   char     *NewValue;
346   char     *Value;
347   int       Position;
348 
349   NewSimul = VasySimulateAddSimul( Simul->WIDTH + 1, Simul->SIGNED );
350 
351   NewValue = NewSimul->VALUE;
352   Value    = Simul->VALUE;
353 
354   for ( Position = 0; Position < Simul->WIDTH; Position++ )
355   {
356     NewValue[ Position + 1 ] = Value[ Position ];
357   }
358 
359   NewValue[ 0 ] = CarryOut;
360   VasySimulateDelSimul( Simul );
361 
362   return( NewSimul );
363 }
364 
365 /*------------------------------------------------------------\
366 |                                                             |
367 |                    VasySimulateExtendSimul                  |
368 |                                                             |
369 \------------------------------------------------------------*/
370 
VasySimulateExtendSimul(Simul,Width)371 static vasysimul *VasySimulateExtendSimul( Simul, Width )
372 
373   vasysimul *Simul;
374   short     Width;
375 {
376   vasysimul *NewSimul;
377   char     *NewValue;
378   char     *Value;
379   int       Position;
380   int       Delta;
381   char      BitSign;
382 
383   Simul = VasySimulateSignSimul( Simul );
384   Delta = Width - Simul->WIDTH;
385 
386   if ( Delta > 0 )
387   {
388     if ( IsVasyDebugLevel2() )
389     {
390       VasyPrintf( stdout, "  --> VasySimulateExtendSimul (%d %d)\n",
391                  Simul->WIDTH, Width );
392       VasySimulateViewSimul( Simul );
393     }
394 
395     Value   = Simul->VALUE;
396     BitSign = Value[ 0 ];
397 
398     NewSimul = VasySimulateAddSimul( Width, 1 );
399     NewValue = NewSimul->VALUE;
400 
401     for ( Position = 0; Position < Delta; Position++ )
402     {
403       NewValue[ Position ] = BitSign;
404     }
405 
406     for ( Position = 0; Position < Simul->WIDTH; Position++ )
407     {
408       NewValue[ Position + Delta ] = Value[ Position ];
409     }
410 
411     VasySimulateDelSimul( Simul );
412     Simul = NewSimul;
413 
414     if ( IsVasyDebugLevel2() )
415     {
416       VasySimulateViewSimul( Simul );
417       VasyPrintf( stdout, "  <-- VasySimulateExtendSimul\n" );
418     }
419   }
420 
421   return( Simul );
422 }
423 
424 /*------------------------------------------------------------\
425 |                                                             |
426 |                    VasySimulateResizeSimul                  |
427 |                                                             |
428 \------------------------------------------------------------*/
429 
VasySimulateResizeSimul(Simul,Width,Signed)430 static vasysimul *VasySimulateResizeSimul( Simul, Width, Signed )
431 
432   vasysimul *Simul;
433   short     Width;
434   short     Signed;
435 {
436   vasysimul *NewSimul;
437   char     *NewValue;
438   char     *Value;
439   int       Position;
440   int       Delta;
441   char      BitSign;
442 
443   if ( IsVasyDebugLevel2() )
444   {
445     VasyPrintf( stdout, "  --> VasySimulateResizeSimul > (%d %d)\n", Width, Signed );
446     VasySimulateViewSimul( Simul );
447   }
448 
449   Value = Simul->VALUE;
450   Delta = Width - Simul->WIDTH;
451 
452   if ( Delta == 0 )
453   {
454 /*
455 **  Target Width is equal => must be convertible
456 */
457     if ( ( Simul->SIGNED != Signed     ) &&
458          ( Value[ 0 ]   == VEX_ONE_ID ) )
459     {
460       VasyWarningLine( VASY_WARNING_IN_SIMULATION, VasyVpnLine, "unconvertible value" );
461     }
462   }
463   else
464   if ( Delta > 0 )
465   {
466 /*
467 **  Target Width is greater => must extend the sign
468 */
469     if ( ( Simul->SIGNED             ) &&
470          ( ! Signed                 ) &&
471          ( Value[ 0 ] == VEX_ONE_ID ) )
472     {
473       VasyErrorLine( VASY_WARNING_IN_SIMULATION, VasyVpnLine, "unconvertible value" );
474     }
475 
476     if ( ( Signed       ) &&
477          ( Simul->SIGNED ) ) BitSign = Value[ 0 ];
478     else                     BitSign = VEX_ZERO_ID;
479 
480     NewSimul  = VasySimulateAddSimul( Width, Signed );
481     NewValue = NewSimul->VALUE;
482 
483     for ( Position = 0; Position < Delta; Position++ )
484     {
485       NewValue[ Position ] = BitSign;
486     }
487 
488     for ( Position = 0; Position < Simul->WIDTH; Position++ )
489     {
490       NewValue[ Position + Delta ] = Value[ Position ];
491     }
492 
493     VasySimulateDelSimul( Simul );
494     Simul = NewSimul;
495   }
496   else
497   {
498 /*
499 **  Target Width is lower => must verify the sign
500 */
501     Delta = - Delta;
502 
503     if ( ( Signed        ) &&
504          ( Simul->SIGNED ) ) BitSign = Value[ 0 ];
505     else                     BitSign = VEX_ZERO_ID;
506 
507     for ( Position = 0; Position < Delta; Position++ )
508     {
509       if ( Value[ Position ] != BitSign )
510       {
511         VasyWarningLine( VASY_WARNING_IN_SIMULATION, VasyVpnLine, "unconvertible value" );
512       }
513     }
514 
515     NewSimul  = VasySimulateAddSimul( Width, Signed );
516     NewValue = NewSimul->VALUE;
517 
518     for ( Position = 0; Position < Width; Position++ )
519     {
520       NewValue[ Position ] = Value[ Position + Delta ];
521     }
522 
523     VasySimulateDelSimul( Simul );
524     Simul = NewSimul;
525   }
526 
527   if ( IsVasyDebugLevel2() )
528   {
529     VasySimulateViewSimul( Simul );
530     VasyPrintf( stdout, "  <-- VasySimulateResizeSimul\n" );
531   }
532 
533   return( Simul );
534 }
535 
536 /*------------------------------------------------------------\
537 |                                                             |
538 |                    VasySimulateIntegerSimul                 |
539 |                                                             |
540 \------------------------------------------------------------*/
541 
VasySimulateIntegerSimul(SimulExpr)542 static long VasySimulateIntegerSimul( SimulExpr )
543 
544   vasysimul *SimulExpr;
545 {
546   char *SimulValue;
547   int   Width;
548   int   Position;
549   long  Value;
550 
551   if ( IsVasyDebugLevel2() )
552   {
553     VasyPrintf( stdout, "  --> VasySimulateIntegerSimul\n" );
554     VasySimulateViewSimul( SimulExpr );
555   }
556 
557   SimulValue = SimulExpr->VALUE;
558   Width      = SimulExpr->WIDTH;
559   Position   = 0;
560   Value      = 0;
561 
562   if ( ( SimulExpr->SIGNED             ) &&
563        ( SimulValue[ 0 ] == VEX_ONE_ID ) )
564   {
565     Value = -1;
566   }
567 
568   for ( Position = 0; Position < Width; Position++ )
569   {
570     Value = Value << 1;
571 
572     if ( SimulValue[ Position ] == VEX_ONE_ID )
573     {
574       Value |= 1;
575     }
576     else
577     if ( SimulValue[ Position ] != VEX_ZERO_ID )
578     {
579       VasyErrorLine( VASY_ERROR_IN_SIMULATION, VasyVpnLine, "not integer value" );
580     }
581   }
582 
583   if ( IsVasyDebugLevel2() )
584   {
585     VasyPrintf( stdout, "  <-- VasySimulateNegSimul %ld\n", Value );
586   }
587 
588   return( Value );
589 }
590 
591 /*------------------------------------------------------------\
592 |                                                             |
593 |                    VasySimulateNegSimul                     |
594 |                                                             |
595 \------------------------------------------------------------*/
596 
VasySimulateNegSimul(SimulExpr)597 static vasysimul *VasySimulateNegSimul( SimulExpr )
598 
599   vasysimul *SimulExpr;
600 {
601   char *SimulValue;
602   int   Position;
603   char  Value1;
604   char  Value;
605   char  Carry;
606   char  Sign;
607 
608   if ( IsVasyDebugLevel2() )
609   {
610     VasyPrintf( stdout, "  --> VasySimulateNegSimul\n" );
611     VasySimulateViewSimul( SimulExpr );
612   }
613 
614   SimulExpr  = VasySimulateSignSimul( SimulExpr );
615   SimulValue = SimulExpr->VALUE;
616 
617   Sign  = SimulValue[ 0 ];
618   Carry = 1;
619 
620   for ( Position = SimulExpr->WIDTH - 1; Position >= 0; Position-- )
621   {
622     if ( SimulValue[ Position ] == VEX_ONE_ID ) Value1 = 0;
623     else                                       Value1 = 1;
624 
625     Value = Value1 ^ Carry;
626     Carry = Value1 & Carry;
627 
628     if ( Value ) Value = VEX_ONE_ID;
629     else         Value = VEX_ZERO_ID;
630 
631     SimulValue[ Position ] = Value;
632   }
633 
634   if ( ( Sign            == VEX_ONE_ID  ) &&
635        ( SimulValue[ 0 ] != VEX_ZERO_ID ) )
636   {
637     SimulExpr = VasySimulateCarryOutSimul( SimulExpr, VEX_ZERO_ID );
638   }
639 
640   if ( IsVasyDebugLevel2() )
641   {
642     VasySimulateViewSimul( SimulExpr );
643     VasyPrintf( stdout, "  <-- VasySimulateNegSimul\n" );
644   }
645 
646   return( SimulExpr );
647 }
648 
649 /*------------------------------------------------------------\
650 |                                                             |
651 |                    VasySimulateSumSimul                     |
652 |                                                             |
653 \------------------------------------------------------------*/
654 
VasySimulateSumSimul(SimulExpr1,SimulExpr2)655 static vasysimul *VasySimulateSumSimul( SimulExpr1, SimulExpr2 )
656 
657   vasysimul *SimulExpr1;
658   vasysimul *SimulExpr2;
659 {
660   char    *SimulValue1;
661   char    *SimulValue2;
662   char     Negative1;
663   char     Negative2;
664   char     Value1;
665   char     Value2;
666   char     Value;
667   char     Carry;
668   int      Position;
669 
670   SimulExpr1 = VasySimulateSignSimul( SimulExpr1 );
671   SimulExpr2 = VasySimulateSignSimul( SimulExpr2 );
672 
673   if ( SimulExpr1->WIDTH > SimulExpr2->WIDTH )
674   {
675     SimulExpr2 = VasySimulateExtendSimul( SimulExpr2, SimulExpr1->WIDTH );
676   }
677   else
678   if ( SimulExpr2->WIDTH > SimulExpr1->WIDTH )
679   {
680     SimulExpr1 = VasySimulateExtendSimul( SimulExpr1, SimulExpr2->WIDTH );
681   }
682 
683   Carry       = 0;
684   SimulValue1 = SimulExpr1->VALUE;
685   SimulValue2 = SimulExpr2->VALUE;
686 
687   Negative1 = ( SimulValue1[ 0 ] == VEX_ONE_ID );
688   Negative2 = ( SimulValue2[ 0 ] == VEX_ONE_ID );
689 
690   for ( Position = SimulExpr1->WIDTH - 1; Position >= 0; Position-- )
691   {
692     Value1 = SimulValue1[ Position ];
693     Value2 = SimulValue2[ Position ];
694 
695     if ( Value1 == VEX_ONE_ID ) Value1 = 1;
696     else                        Value1 = 0;
697 
698     if ( Value2 == VEX_ONE_ID ) Value2 = 1;
699     else                        Value2 = 0;
700 
701     Value = Value1 ^ Value2 ^ Carry;
702     Carry = ( Value1 & Value2 ) |
703             ( Value1 & Carry  ) |
704             ( Value2 & Carry  ) ;
705 
706     if ( Value ) Value = VEX_ONE_ID;
707     else         Value = VEX_ZERO_ID;
708 
709     SimulValue1[ Position ] = Value;
710   }
711 
712   if ( ( Negative1 ) &&
713        ( Negative2 ) )
714   {
715     if ( SimulValue1[ 0 ] == VEX_ZERO_ID )
716     {
717       SimulExpr1 = VasySimulateCarryOutSimul( SimulExpr1, VEX_ONE_ID );
718     }
719   }
720   else
721   if ( ( ! Negative1 ) &&
722        ( ! Negative2 ) )
723   {
724     if ( SimulValue1[ 0 ] == VEX_ONE_ID )
725     {
726       SimulExpr1 = VasySimulateCarryOutSimul( SimulExpr1, VEX_ZERO_ID );
727     }
728   }
729 
730   VasySimulateDelSimul( SimulExpr2 );
731 
732   return( SimulExpr1 );
733 }
734 
735 /*------------------------------------------------------------\
736 |                                                             |
737 |                    VasySimulateAbsSimul                     |
738 |                                                             |
739 \------------------------------------------------------------*/
740 
VasySimulateAbsSimul(SimulExpr)741 static vasysimul *VasySimulateAbsSimul( SimulExpr )
742 
743   vasysimul *SimulExpr;
744 {
745   char *SimulValue;
746   int   Position;
747   char  Value1;
748   char  Value;
749   char  Carry;
750   char  Sign;
751 
752   if ( IsVasyDebugLevel2() )
753   {
754     VasyPrintf( stdout, "  --> VasySimulateAbsSimul\n" );
755     VasySimulateViewSimul( SimulExpr );
756   }
757 
758   SimulValue = SimulExpr->VALUE;
759 
760   Sign = SimulValue[ 0 ];
761 
762   if ( ( Sign == VEX_ONE_ID ) &&
763        ( SimulExpr->SIGNED  ) )
764   {
765     Carry = 1;
766 
767     for ( Position = SimulExpr->WIDTH - 1; Position >= 0; Position-- )
768     {
769       if ( SimulValue[ Position ] == VEX_ONE_ID ) Value1 = 0;
770       else                                        Value1 = 1;
771 
772       Value = Value1 ^ Carry;
773       Carry = Value1 & Carry;
774 
775       if ( Value ) Value = VEX_ONE_ID;
776       else         Value = VEX_ZERO_ID;
777 
778       SimulValue[ Position ] = Value;
779     }
780 
781     if ( ( Sign            == VEX_ONE_ID  ) &&
782          ( SimulValue[ 0 ] != VEX_ZERO_ID ) )
783     {
784       SimulExpr = VasySimulateCarryOutSimul( SimulExpr, VEX_ZERO_ID );
785     }
786   }
787 
788   if ( IsVasyDebugLevel2() )
789   {
790     VasySimulateViewSimul( SimulExpr );
791     VasyPrintf( stdout, "  <-- VasySimulateAbsSimul\n" );
792   }
793 
794   return( SimulExpr );
795 }
796 
797 
798 /*------------------------------------------------------------\
799 |                                                             |
800 |                      VasySimulateVexAbs                     |
801 |                                                             |
802 \------------------------------------------------------------*/
803 
VasySimulateVexAbs(Expr)804 static vasysimul *VasySimulateVexAbs( Expr )
805 
806   vexexpr *Expr;
807 {
808   vasysimul *SimulExpr;
809   vexexpr *Operand;
810 
811   Operand   = GetVexOperand( Expr->OPERAND );
812   SimulExpr  = VasySimulateVex( Operand );
813   SimulExpr  = VasySimulateAbsSimul( SimulExpr );
814 
815   return( SimulExpr );
816 }
817 
818 
819 /*------------------------------------------------------------\
820 |                                                             |
821 |                      VasySimulateVexNeg                     |
822 |                                                             |
823 \------------------------------------------------------------*/
824 
VasySimulateVexNeg(Expr)825 static vasysimul *VasySimulateVexNeg( Expr )
826 
827   vexexpr *Expr;
828 {
829   vasysimul *SimulExpr;
830   vexexpr *Operand;
831 
832   Operand   = GetVexOperand( Expr->OPERAND );
833   SimulExpr  = VasySimulateVex( Operand );
834   SimulExpr  = VasySimulateNegSimul( SimulExpr );
835 
836   return( SimulExpr );
837 }
838 
839 /*------------------------------------------------------------\
840 |                                                             |
841 |                     VasySimulateVexSum                      |
842 |                                                             |
843 \------------------------------------------------------------*/
844 
VasySimulateVexSum(Expr)845 static vasysimul *VasySimulateVexSum( Expr )
846 
847   vexexpr *Expr;
848 {
849   vasysimul        *SimulExpr1;
850   vasysimul        *SimulExpr2;
851   chain_list     *ScanChain;
852   vexexpr        *Operand;
853   long            Oper;
854 
855   Oper = GetVexOperValue( Expr );
856 
857   ScanChain = Expr->OPERAND;
858   Operand   = GetVexOperand( ScanChain );
859   SimulExpr1 = VasySimulateVex( Operand );
860   ScanChain = ScanChain->NEXT;
861 
862   while ( ScanChain != (chain_list *)0 )
863   {
864     Operand   = GetVexOperand( ScanChain );
865     SimulExpr2 = VasySimulateVex( Operand );
866 
867     if ( Oper == VEX_SUB )
868     {
869       SimulExpr2 = VasySimulateNegSimul( SimulExpr2 );
870     }
871 
872     SimulExpr1 = VasySimulateSumSimul( SimulExpr1, SimulExpr2 );
873 
874     ScanChain = ScanChain->NEXT;
875   }
876 
877   return( SimulExpr1 );
878 }
879 
880 /*------------------------------------------------------------\
881 |                                                             |
882 |                     VasySimulateVexEqual                    |
883 |                                                             |
884 \------------------------------------------------------------*/
885 
VasySimulateVexEqual(Expr)886 static vasysimul *VasySimulateVexEqual( Expr )
887 
888   vexexpr *Expr;
889 {
890   vasysimul       *SimulExpr1;
891   vasysimul       *SimulExpr2;
892   char           *SimulValue1;
893   char           *SimulValue2;
894   chain_list     *ScanChain;
895   vexexpr        *Operand;
896   char            Equal;
897   long            Oper;
898   int             Position;
899 
900   Oper = GetVexOperValue( Expr );
901 
902   ScanChain  = Expr->OPERAND;
903   Operand    = GetVexOperand( ScanChain );
904   SimulExpr1  = VasySimulateVex( Operand );
905 
906   ScanChain  = ScanChain->NEXT;
907   Operand    = GetVexOperand( ScanChain );
908   SimulExpr2  = VasySimulateVex( Operand );
909 
910   if ( SimulExpr1->WIDTH > SimulExpr2->WIDTH )
911   {
912     SimulExpr2 = VasySimulateExtendSimul( SimulExpr2, SimulExpr1->WIDTH );
913   }
914   else
915   if ( SimulExpr2->WIDTH > SimulExpr1->WIDTH )
916   {
917     SimulExpr1 = VasySimulateExtendSimul( SimulExpr1, SimulExpr2->WIDTH );
918   }
919 
920   SimulValue1 = SimulExpr1->VALUE;
921   SimulValue2 = SimulExpr2->VALUE;
922 
923   if ( Oper == VEX_EQ ) Equal = 1;
924   else                  Equal = 0;
925 
926   for ( Position = 0; Position < SimulExpr2->WIDTH; Position++ )
927   {
928     if ( SimulValue1[ Position ] != SimulValue2[ Position ] )
929     {
930       Equal = ! Equal; break;
931     }
932   }
933 
934   VasySimulateDelSimul( SimulExpr1 );
935   VasySimulateDelSimul( SimulExpr2 );
936 
937   SimulExpr1 = VasySimulateAddSimul( 1, 0 );
938 
939   if ( Equal ) SimulExpr1->VALUE[ 0 ] = VEX_ONE_ID;
940   else         SimulExpr1->VALUE[ 0 ] = VEX_ZERO_ID;
941 
942   return( SimulExpr1 );
943 }
944 
945 /*------------------------------------------------------------\
946 |                                                             |
947 |                     VasySimulateVexCompare                  |
948 |                                                             |
949 \------------------------------------------------------------*/
950 
VasySimulateVexCompare(Expr)951 static vasysimul *VasySimulateVexCompare( Expr )
952 
953   vexexpr *Expr;
954 {
955   vasysimul       *SimulExpr1;
956   vasysimul       *SimulExpr2;
957   char           *SimulValue1;
958   chain_list     *ScanChain;
959   vexexpr        *Operand;
960   long            Oper;
961   short           Compare;
962   short           Negative;
963   short           Zero;
964   int             Position;
965 
966   Oper = GetVexOperValue( Expr );
967 
968   ScanChain = Expr->OPERAND;
969   Operand   = GetVexOperand( ScanChain );
970   SimulExpr1 = VasySimulateVex( Operand );
971 
972   ScanChain = ScanChain->NEXT;
973   Operand   = GetVexOperand( ScanChain );
974   SimulExpr2 = VasySimulateVex( Operand );
975 
976   SimulExpr2 = VasySimulateNegSimul( SimulExpr2 );
977   SimulExpr1 = VasySimulateSumSimul( SimulExpr1, SimulExpr2 );
978 
979   SimulValue1 = SimulExpr1->VALUE;
980 
981   Negative = ( SimulValue1[ 0 ] == VEX_ONE_ID );
982   Zero     = 1;
983 
984   for ( Position = SimulExpr1->WIDTH - 1; Position >= 0; Position-- )
985   {
986     if ( SimulValue1[ Position ] != VEX_ZERO_ID )
987     {
988       Zero = 0; break;
989     }
990   }
991 
992   if ( Oper == VEX_LT ) Compare = (   Negative ) && ( ! Zero );
993   else
994   if ( Oper == VEX_GT ) Compare = ( ! Negative ) && ( ! Zero );
995   else
996   if ( Oper == VEX_LE ) Compare = (   Negative ) || (   Zero );
997   else
998                         Compare = ( ! Negative ) || (   Zero );
999 
1000   VasySimulateDelSimul( SimulExpr1 );
1001 
1002   SimulExpr1 = VasySimulateAddSimul( 1, 0 );
1003 
1004   if ( Compare ) SimulExpr1->VALUE[ 0 ] = VEX_ONE_ID;
1005   else           SimulExpr1->VALUE[ 0 ] = VEX_ZERO_ID;
1006 
1007   return( SimulExpr1 );
1008 }
1009 
1010 /*------------------------------------------------------------\
1011 |                                                             |
1012 |                     VasySimulateVexAtom                     |
1013 |                                                             |
1014 \------------------------------------------------------------*/
1015 
VasySimulateVexAtom(Atom,Effec)1016 static vasysimul *VasySimulateVexAtom( Atom, Effec )
1017 
1018   vexexpr *Atom;
1019   short    Effec;
1020 {
1021   vpndecl_list *VpnDeclar;
1022   vpnsym       *VpnSymbol;
1023   vasysimul     *SimulAtom;
1024   char         *SimulValue;
1025   char         *AtomValue;
1026   int           Position;
1027   int           Delta;
1028   short         Signed;
1029 
1030   AtomValue = GetVexAtomValue( Atom );
1031 
1032   if ( IsVexAtomSigned( Atom ) ) Signed = 1;
1033   else                           Signed = 0;
1034 
1035   SimulAtom  = VasySimulateAddSimul( Atom->WIDTH, Signed );
1036   SimulValue = SimulAtom->VALUE;
1037 
1038   if ( IsVexAtomLiteral( Atom ) )
1039   {
1040     for ( Position = 0; Position < Atom->WIDTH; Position++ )
1041     {
1042       SimulValue[ Position ] = getvexliteralid( AtomValue[ Position + 1 ] );
1043     }
1044   }
1045   else
1046   {
1047     VpnDeclar = searchvpndeclall( VasyFigure, AtomValue );
1048     Delta     = getvexvectorpos( VpnDeclar->VEX_ATOM, Atom->LEFT );
1049 
1050     for ( Position = 0; Position < Atom->WIDTH; Position++ )
1051     {
1052       VpnSymbol = &VpnDeclar->DECL_SYM[ Position + Delta ];
1053 
1054       if ( Effec ) SimulValue[ Position ] = VpnSymbol->EFFEC;
1055       else         SimulValue[ Position ] = VpnSymbol->DRIVE;
1056     }
1057   }
1058 
1059   return( SimulAtom );
1060 }
1061 
1062 /*------------------------------------------------------------\
1063 |                                                             |
1064 |                     VasySimulateVexSlice                    |
1065 |                                                             |
1066 \------------------------------------------------------------*/
1067 
VasySimulateVexSlice(Expr)1068 static vasysimul *VasySimulateVexSlice( Expr )
1069 
1070   vexexpr *Expr;
1071 {
1072   vasysimul   *SimulExpr1;
1073   vasysimul   *SimulExpr2;
1074   char       *SimulValue1;
1075   char       *SimulValue2;
1076   chain_list *ScanChain;
1077   vexexpr    *VexAtom;
1078   vexexpr    *Operand;
1079   long        Oper;
1080   int         IndexFrom;
1081   int         IndexTo;
1082   int         IndexMin;
1083   int         IndexMax;
1084   int         Index;
1085   int         Width;
1086   int         Position;
1087   int         ScanPos;
1088   short       Signed;
1089 
1090   Oper = GetVexOperValue( Expr );
1091 
1092   ScanChain   = Expr->OPERAND;
1093   VexAtom     = GetVexOperand( ScanChain );
1094   SimulExpr1  = VasySimulateVex( VexAtom );
1095   SimulValue1 = SimulExpr1->VALUE;
1096 
1097   ScanChain  = ScanChain->NEXT;
1098   Operand    = GetVexOperand( ScanChain );
1099   SimulExpr2 = VasySimulateVex( Operand );
1100 
1101   IndexFrom = VasySimulateIntegerSimul( SimulExpr2 );
1102   VasySimulateDelSimul( SimulExpr2 );
1103 
1104   if ( Oper != VEX_INDEX )
1105   {
1106     ScanChain  = ScanChain->NEXT;
1107     Operand    = GetVexOperand( ScanChain );
1108     SimulExpr2 = VasySimulateVex( Operand );
1109 
1110     IndexTo = VasySimulateIntegerSimul( SimulExpr2 );
1111     VasySimulateDelSimul( SimulExpr2 );
1112   }
1113   else
1114   {
1115     IndexTo = IndexFrom;
1116   }
1117 
1118   if ( IsVexAtomSigned( VexAtom ) ) Signed = 1;
1119   else                              Signed = 0;
1120 
1121   if ( Oper == VEX_DOWNTO )
1122   {
1123     IndexMin = IndexTo;
1124     IndexMax = IndexFrom;
1125   }
1126   else
1127   {
1128     IndexMin = IndexFrom;
1129     IndexMax = IndexTo;
1130   }
1131 
1132   Width = ( IndexMax - IndexMin ) + 1;
1133 
1134   if ( Width <= 0 )
1135   {
1136     VasyErrorLine( VASY_ERROR_IN_SIMULATION, VasyVpnLine, "negative width" );
1137   }
1138 
1139   SimulExpr2  = VasySimulateAddSimul( Width, Signed );
1140   SimulValue2 = SimulExpr2->VALUE;
1141 
1142   Position = 0;
1143 
1144   for ( Index = IndexMin; Index <= IndexMax; Index++ )
1145   {
1146     ScanPos = getvexvectorpos( VexAtom, Index );
1147 
1148     if ( ScanPos == -1 )
1149     {
1150       VasyErrorLine( VASY_ERROR_IN_SIMULATION, VasyVpnLine, "index out of bound" );
1151     }
1152 
1153     SimulValue2[ Position ] = SimulValue1[ ScanPos ];
1154   }
1155 
1156   VasySimulateDelSimul( SimulExpr1 );
1157 
1158   return( SimulExpr2 );
1159 }
1160 
1161 
1162 /*------------------------------------------------------------\
1163 |                                                             |
1164 |                     VasySimulateVexConcat                   |
1165 |                                                             |
1166 \------------------------------------------------------------*/
1167 
VasySimulateVexConcat(Expr)1168 static vasysimul *VasySimulateVexConcat( Expr )
1169 
1170   vexexpr *Expr;
1171 {
1172   vasysimul        *SimulExpr;
1173   vasysimul        *SimulOper;
1174   char           *SimulValue;
1175   chain_list     *ScanChain;
1176   vexexpr        *Operand;
1177   int             Position;
1178   int             ScanPos;
1179   int             Width;
1180 
1181   SimulExpr  = VasySimulateAddSimul( Expr->WIDTH, 0 );
1182   SimulValue = SimulExpr->VALUE;
1183   Position  = 0;
1184 
1185   for ( ScanChain  = Expr->OPERAND;
1186         ScanChain != (chain_list *)0;
1187         ScanChain  = ScanChain->NEXT )
1188   {
1189     Operand  = GetVexOperand( ScanChain );
1190     Width    = Operand->WIDTH;
1191     SimulOper = VasySimulateVex( Operand );
1192 
1193     for ( ScanPos = 0; ScanPos < Width; ScanPos++ )
1194     {
1195       SimulValue[ Position++ ] = SimulOper->VALUE[ ScanPos ];
1196     }
1197 
1198     VasySimulateDelSimul( SimulOper );
1199   }
1200 
1201   return( SimulExpr );
1202 }
1203 
1204 /*------------------------------------------------------------\
1205 |                                                             |
1206 |                     VasySimulateVexDriver                   |
1207 |                                                             |
1208 \------------------------------------------------------------*/
1209 
VasySimulateVexDriver(Expr)1210 static vasysimul *VasySimulateVexDriver( Expr )
1211 
1212   vexexpr *Expr;
1213 {
1214   vexexpr  *Atom;
1215   vasysimul *SimulExpr;
1216 
1217   Atom = GetVexOperand( Expr->OPERAND );
1218   SimulExpr  = VasySimulateVexAtom( Atom, 0 );
1219 
1220   return( SimulExpr );
1221 }
1222 
1223 /*------------------------------------------------------------\
1224 |                                                             |
1225 |                     VasySimulateVexEvent                    |
1226 |                                                             |
1227 \------------------------------------------------------------*/
1228 
VasySimulateVexEvent(Expr)1229 static vasysimul *VasySimulateVexEvent( Expr )
1230 
1231   vexexpr *Expr;
1232 {
1233   vpndecl_list   *VpnDeclar;
1234   vpnsym         *VpnSymbol;
1235   vexexpr        *Atom;
1236   vasysimul        *SimulExpr;
1237   char           *SimulValue;
1238   char           *AtomValue;
1239   int             Delta;
1240 
1241   SimulExpr  = VasySimulateAddSimul( 1, 0 );
1242   SimulValue = SimulExpr->VALUE;
1243 
1244   Atom      = GetVexOperand( Expr->OPERAND );
1245   AtomValue = GetVexAtomValue( Atom );
1246 
1247   VpnDeclar = searchvpndeclall( VasyFigure, AtomValue );
1248   Delta     = getvexvectorpos( VpnDeclar->VEX_ATOM, Atom->LEFT );
1249   VpnSymbol = &VpnDeclar->DECL_SYM[ Delta ];
1250 
1251   if ( VpnSymbol->EVENT ) SimulValue[ 0 ] = VEX_ONE_ID;
1252   else                    SimulValue[ 0 ] = VEX_ZERO_ID;
1253 
1254   return( SimulExpr );
1255 }
1256 
1257 /*------------------------------------------------------------\
1258 |                                                             |
1259 |                     VasySimulateVexLogic                    |
1260 |                                                             |
1261 \------------------------------------------------------------*/
1262 
VasySimulateVexLogic(Expr)1263 static vasysimul *VasySimulateVexLogic( Expr )
1264 
1265   vexexpr *Expr;
1266 {
1267   vasysimul   *SimulExpr1;
1268   vasysimul   *SimulExpr2;
1269   char       *SimulValue1;
1270   char       *SimulValue2;
1271   chain_list *ScanChain;
1272   vexexpr    *Operand;
1273   int         Value1;
1274   int         Value2;
1275   long        Oper;
1276   short       Width;
1277   int         Position;
1278   int         Negative;
1279 
1280   Oper  = GetVexOperValue( Expr );
1281   Width = Expr->WIDTH;
1282 
1283   Negative = isvexnegativeoper( Oper );
1284 
1285   if ( Negative ) Oper = getvexnotoper( Oper );
1286 
1287   if ( Oper == VEX_IFT ) Oper = VEX_AND;
1288 
1289   ScanChain  = Expr->OPERAND;
1290   Operand    = GetVexOperand( ScanChain );
1291   SimulExpr1  = VasySimulateVex( Operand );
1292   SimulValue1 = SimulExpr1->VALUE;
1293 
1294   ScanChain = ScanChain->NEXT;
1295 
1296   while ( ScanChain != (chain_list *)0 )
1297   {
1298     Operand    = GetVexOperand( ScanChain );
1299     SimulExpr2  = VasySimulateVex( Operand );
1300     SimulValue2 = SimulExpr2->VALUE;
1301 
1302     for ( Position = 0; Position < Width; Position++ )
1303     {
1304       Value1 = SimulValue1[ Position ];
1305       Value2 = SimulValue2[ Position ];
1306 
1307       if ( Oper == VEX_AND )
1308       {
1309         Value1 = VasyTruthTableAnd[ Value1 ][ Value2 ];
1310       }
1311       else
1312       if ( Oper == VEX_OR )
1313       {
1314         Value1 = VasyTruthTableOr[ Value1 ][ Value2 ];
1315       }
1316       else
1317       {
1318         Value1 = VasyTruthTableXor[ Value1 ][ Value2 ];
1319       }
1320 
1321       SimulValue1[ Position ] = Value1;
1322     }
1323 
1324     VasySimulateDelSimul( SimulExpr2 );
1325     ScanChain = ScanChain->NEXT;
1326   }
1327 
1328   if ( Negative )
1329   {
1330     for ( Position = 0; Position < Width; Position++ )
1331     {
1332       Value1 = SimulValue1[ Position ];
1333 
1334       SimulValue1[ Position ] = VasyTruthTableNot[ Value1 ];
1335     }
1336   }
1337 
1338   return( SimulExpr1 );
1339 }
1340 
1341 /*------------------------------------------------------------\
1342 |                                                             |
1343 |                     VasySimulateVex                         |
1344 |                                                             |
1345 \------------------------------------------------------------*/
1346 
VasySimulateVex(Expr)1347 static vasysimul *VasySimulateVex( Expr )
1348 
1349   vexexpr *Expr;
1350 {
1351   vasysimul  *SimulExpr;
1352   long       Oper;
1353 
1354   SimulExpr = (vasysimul *)0;
1355 
1356   if ( IsVexNodeAtom( Expr ) )
1357   {
1358     SimulExpr = VasySimulateVexAtom( Expr, 1 );
1359   }
1360   else
1361   if ( IsVexNodeOper( Expr ) )
1362   {
1363     Oper = GetVexOperValue( Expr );
1364 
1365     if ( VasySimulOperFunc[ Oper ] == NULL )
1366     {
1367       VasyErrorLine( VASY_NOT_YET_IMPLEMENTED_ERROR, VasyVpnLine, "Operator" );
1368     }
1369 
1370     SimulExpr = (*VasySimulOperFunc[ Oper ])( Expr );
1371   }
1372   else
1373   {
1374     VasyErrorLine( VASY_NOT_YET_IMPLEMENTED_ERROR, VasyVpnLine,  "Function" );
1375   }
1376 
1377   if ( IsVasyDebugLevel2() )
1378   {
1379     VasyPrintf( stdout, "  +++ VasySimulateVex " );
1380     viewvexexprboundln( Expr );
1381   }
1382 
1383   if ( IsVasyDebugLevel2() )
1384   {
1385     VasySimulateViewSimul( SimulExpr );
1386   }
1387 
1388   return( SimulExpr );
1389 }
1390 
1391 /*------------------------------------------------------------\
1392 |                                                             |
1393 |                     VasySimulateVexGuard                    |
1394 |                                                             |
1395 \------------------------------------------------------------*/
1396 
VasySimulateVexGuard(VpnFigure,VexGuard)1397 static int VasySimulateVexGuard( VpnFigure, VexGuard )
1398 
1399   vpnfig_list  *VpnFigure;
1400   vexexpr      *VexGuard;
1401 {
1402   vasysimul *GuardSimul;
1403   char    *GuardValue;
1404   int      Guard;
1405 
1406   VasyFigure  = VpnFigure;
1407   GuardSimul  = VasySimulateVex( VexGuard );
1408   GuardValue = GuardSimul->VALUE;
1409 
1410   if ( GuardValue[ 0 ] == VEX_ONE_ID ) Guard = 1;
1411   else                                 Guard = 0;
1412 
1413   VasySimulateDelSimul( GuardSimul );
1414 
1415   return( Guard );
1416 }
1417 
1418 /*------------------------------------------------------------\
1419 |                                                             |
1420 |                     VasySimulateVexExpr                     |
1421 |                                                             |
1422 \------------------------------------------------------------*/
1423 
VasySimulateVexExpr(VpnFigure,VexAtom,VexExpr)1424 vasysimul *VasySimulateVexExpr( VpnFigure, VexAtom, VexExpr )
1425 
1426   vpnfig_list  *VpnFigure;
1427   vexexpr      *VexAtom;
1428   vexexpr      *VexExpr;
1429 {
1430   vasysimul *SimulExpr;
1431   short    Signed;
1432 
1433   VasyFigure  = VpnFigure;
1434   SimulExpr   = VasySimulateVex( VexExpr );
1435 
1436   if ( IsVexAtomSigned( VexAtom ) ) Signed = 1;
1437   else                              Signed = 0;
1438 
1439   SimulExpr = VasySimulateResizeSimul( SimulExpr, VexAtom->WIDTH, Signed );
1440 
1441   return( SimulExpr );
1442 }
1443 
1444 /*------------------------------------------------------------\
1445 |                                                             |
1446 |                  VasySimulateGetVpnActAtom                  |
1447 |                                                             |
1448 \------------------------------------------------------------*/
1449 
VasySimulateGetVpnActAtom(VpnFigure,VpnAction)1450 static vexexpr *VasySimulateGetVpnActAtom( VpnFigure, VpnAction )
1451 
1452   vpnfig_list *VpnFigure;
1453   vpnact_list *VpnAction;
1454 {
1455   vasysimul   *SimulExpr1;
1456   chain_list *ScanChain;
1457   vexexpr    *VexExpr;
1458   vexexpr    *VexAtom;
1459   vexexpr    *Operand;
1460   long        Oper;
1461   int         IndexFrom;
1462   int         IndexTo;
1463   int         IndexMin;
1464   int         IndexMax;
1465   int         Width;
1466   int         PosMin;
1467   int         PosMax;
1468 
1469   VexExpr = VpnAction->VEX_ATOM;
1470 
1471   if ( IsVexNodeAtom( VexExpr ) ) return( VexExpr );
1472 
1473   if ( ! IsVexNodeOper( VexExpr ) )
1474   {
1475     VasyErrorLine( VASY_ERROR_IN_SIMULATION, VpnAction->LINE, "bad assigment" );
1476   }
1477 
1478   Oper = GetVexOperValue( VexExpr );
1479 
1480   if ( ( Oper != VEX_INDEX  ) &&
1481        ( Oper != VEX_DOWNTO ) &&
1482        ( Oper != VEX_TO     ) )
1483   {
1484     VasyErrorLine( VASY_ERROR_IN_SIMULATION, VpnAction->LINE, "bad assigment" );
1485   }
1486 
1487   VasyFigure  = VpnFigure;
1488   VasyVpnLine = VpnAction->LINE;
1489 
1490   ScanChain  = VexExpr->OPERAND;
1491   VexAtom    = GetVexOperand( ScanChain );
1492 
1493   ScanChain  = ScanChain->NEXT;
1494   Operand    = GetVexOperand( ScanChain );
1495   SimulExpr1 = VasySimulateVex( Operand );
1496 
1497   IndexFrom  = VasySimulateIntegerSimul( SimulExpr1 );
1498   VasySimulateDelSimul( SimulExpr1 );
1499 
1500   if ( Oper != VEX_INDEX )
1501   {
1502     ScanChain  = ScanChain->NEXT;
1503     Operand    = GetVexOperand( ScanChain );
1504     SimulExpr1 = VasySimulateVex( Operand );
1505 
1506     IndexTo = VasySimulateIntegerSimul( SimulExpr1 );
1507     VasySimulateDelSimul( SimulExpr1 );
1508   }
1509   else
1510   {
1511     IndexTo = IndexFrom;
1512   }
1513 
1514   VexExpr = dupvexnode( VexAtom );
1515 
1516   if ( Oper == VEX_DOWNTO )
1517   {
1518     IndexMin = IndexTo;
1519     IndexMax = IndexFrom;
1520 
1521     SetVexAtomDown( VexExpr );
1522   }
1523   else
1524   {
1525     IndexMin = IndexFrom;
1526     IndexMax = IndexTo;
1527 
1528     SetVexAtomUp( VexExpr );
1529   }
1530 
1531   Width = ( IndexMax - IndexMin ) + 1;
1532 
1533   if ( Width <= 0 )
1534   {
1535     VasyErrorLine( VASY_ERROR_IN_SIMULATION, VpnAction->LINE, "negative width" );
1536   }
1537 
1538   PosMin = getvexvectorpos( VexAtom, IndexMin );
1539   PosMax = getvexvectorpos( VexAtom, IndexMax );
1540 
1541   if ( ( PosMin == -1 ) ||
1542        ( PosMax == -1 ) )
1543   {
1544     VasyErrorLine( VASY_ERROR_IN_SIMULATION, VpnAction->LINE, "index out of bound" );
1545   }
1546 
1547   VexExpr->LEFT  = IndexFrom;
1548   VexExpr->RIGHT = IndexTo;
1549   VexExpr->WIDTH = Width;
1550 
1551   SetVexAtomStaWidth( VexExpr );
1552 
1553   return( VexExpr );
1554 }
1555 
1556 /*------------------------------------------------------------\
1557 |                                                             |
1558 |                     VasySimulateVpnAct                      |
1559 |                                                             |
1560 \------------------------------------------------------------*/
1561 
VasySimulateVpnAct(VpnFigure,VpnProc,VpnAction)1562 static void VasySimulateVpnAct( VpnFigure, VpnProc, VpnAction )
1563 
1564   vpnfig_list  *VpnFigure;
1565   vpnproc_list *VpnProc;
1566   vpnact_list  *VpnAction;
1567 {
1568   vpndecl_list *AsgDeclar;
1569   vpnsym       *AsgSymbol;
1570   vexexpr      *AsgAtom;
1571   vexexpr      *AsgExpr;
1572   vasysimul     *AsgSimul;
1573   char         *AsgValue;
1574   char         *AtomValue;
1575   int           AsgWidth;
1576   int           AsgIndex;
1577   int           Position;
1578 
1579   VasyVpnLine = VpnAction->LINE;
1580 
1581   AsgAtom = VasySimulateGetVpnActAtom( VpnFigure, VpnAction );
1582   AsgExpr = VpnAction->VEX_EXPR;
1583 
1584   if ( IsVasyDebugLevel1() )
1585   {
1586     VasyPrintf( stdout, ">> Simulation Of " );
1587     viewvexexprbound( AsgAtom );
1588     fprintf( stdout, " : " );
1589     viewvexexprboundln( AsgExpr );
1590   }
1591 
1592   AsgSimul = VasySimulateVexExpr( VpnFigure, AsgAtom, AsgExpr );
1593   AsgValue = AsgSimul->VALUE;
1594 
1595   AtomValue = GetVexAtomValue( AsgAtom );
1596   AsgDeclar = searchvpndeclall( VpnFigure, AtomValue );
1597   AsgWidth  = AsgAtom->WIDTH;
1598 
1599   for ( Position = 0; Position < AsgWidth; Position++ )
1600   {
1601     AsgIndex  = getvexvectorindex( AsgAtom, Position );
1602     AsgSymbol = getvpnsymdecl( AsgDeclar, AsgIndex );
1603 
1604     if ( ( AsgDeclar->TYPE == VPN_DECLAR_DEFINE   ) ||
1605          ( AsgDeclar->TYPE == VPN_DECLAR_VARIABLE ) )
1606     {
1607       AsgSymbol->EFFEC = AsgValue[ Position ];
1608     }
1609     else
1610     {
1611       AsgSymbol->DRIVE = AsgValue[ Position ];
1612     }
1613   }
1614 
1615   if ( IsVasyDebugLevel1() )
1616   {
1617     VasySimulateViewSimul( AsgSimul );
1618   }
1619 
1620   VasySimulateDelSimul( AsgSimul );
1621 
1622   if ( IsVasyDebugLevel1() )
1623   {
1624     VasyPrintf( stdout, "<<\n" );
1625   }
1626 }
1627 
1628 /*------------------------------------------------------------\
1629 |                                                             |
1630 |                   VasySimulateVpnPlace                      |
1631 |                                                             |
1632 \------------------------------------------------------------*/
1633 
VasySimulateVpnPlace(VpnFigure,VpnProc,BeginPlace)1634 static int VasySimulateVpnPlace( VpnFigure, VpnProc, BeginPlace )
1635 
1636   vpnfig_list   *VpnFigure;
1637   vpnproc_list  *VpnProc;
1638   vpnplace_list *BeginPlace;
1639 {
1640   chain_list     *ScanTrans;
1641   vpnarc         *VpnArc;
1642   vpntrans_list  *VpnTrans;
1643   vpnplace_list  *VpnPlace;
1644   vpnact_list    *VpnAct;
1645 
1646   VpnPlace = (vpnplace_list *)0;
1647 
1648   do
1649   {
1650     if ( IsVasySimulateLoop( BeginPlace ) )
1651     {
1652       VasyErrorLine( VASY_LOOP_IN_SIMULATION, BeginPlace->LINE, BeginPlace->NAME );
1653     }
1654 
1655     IncVasySimulateLoop( BeginPlace );
1656 
1657     VpnTrans = (vpntrans_list *)0;
1658 
1659     for ( ScanTrans  = BeginPlace->TRANS_OUT;
1660           ScanTrans != (chain_list *)0;
1661           ScanTrans  = ScanTrans->NEXT )
1662     {
1663       VpnArc   = GetVpnArc( ScanTrans );
1664       VpnTrans = GetVpnArcTargetTrans( VpnArc );
1665       VpnArc   = GetVpnArc( VpnTrans->PLACE_OUT );
1666       VpnPlace = GetVpnArcTargetPlace( VpnArc );
1667 
1668       if ( VpnTrans->VEX_GUARD != (vexexpr *)0 )
1669       {
1670         VasyVpnLine = VpnPlace->LINE;
1671 
1672         if ( VasySimulateVexGuard( VpnFigure, VpnTrans->VEX_GUARD ) )
1673         {
1674           break;
1675         }
1676       }
1677     }
1678 
1679     if ( VpnTrans->TYPE == VPN_TRANS_INF_WAIT )
1680     {
1681       VpnProc->ELABO = VpnTrans;
1682 
1683       BeginPlace->TOKEN = 1;
1684 
1685       break;
1686     }
1687 
1688     for ( VpnAct  = VpnTrans->ACT;
1689           VpnAct != (vpnact_list *)0;
1690           VpnAct  = VpnAct->NEXT )
1691     {
1692       VasySimulateVpnAct( VpnFigure, VpnProc, VpnAct );
1693     }
1694 
1695     BeginPlace = VpnPlace;
1696   }
1697   while ( 1 );
1698 
1699   for ( VpnPlace  = VpnProc->PLACE;
1700         VpnPlace != (vpnplace_list *)0;
1701         VpnPlace  = VpnPlace->NEXT )
1702   {
1703     ClearVasySimulateLoop( VpnPlace );
1704   }
1705 
1706   return( 0 );
1707 }
1708 
1709 /*------------------------------------------------------------\
1710 |                                                             |
1711 |                     VasySimulateVpnProc                     |
1712 |                                                             |
1713 \------------------------------------------------------------*/
1714 
VasySimulateVpnProc(VpnFigure,VpnProc)1715 void VasySimulateVpnProc( VpnFigure, VpnProc )
1716 
1717   vpnfig_list  *VpnFigure;
1718   vpnproc_list *VpnProc;
1719 {
1720   vpnplace_list *VpnPlace;
1721   vpnplace_list *ElaboPlace;
1722   vpntrans_list *ElaboTrans;
1723 /*\
1724   vpntrans_list *VpnTrans;
1725   chain_list    *ScanTrans;
1726 \*/
1727   vpnarc        *VpnArc;
1728 
1729   if ( IsVasyDebugLevel0() )
1730   {
1731     VasyPrintf( stdout, "  --> VasySimulateVpnProc %s\n", VpnProc->NAME );
1732   }
1733 
1734   ElaboTrans = VpnProc->ELABO;
1735   VpnArc     = GetVpnArc( ElaboTrans->PLACE_IN );
1736   ElaboPlace = GetVpnArcSourcePlace( VpnArc );
1737 
1738   VpnArc   = GetVpnArc( ElaboTrans->PLACE_OUT );
1739   VpnPlace = GetVpnArcTargetPlace( VpnArc );
1740 /*
1741 **  Change the first Sup_Wait transition
1742 */
1743   ElaboPlace->TOKEN = 0;
1744 
1745   VpnProc->ELABO = (vpntrans_list *)0;
1746 
1747   if ( ElaboTrans->TYPE == VPN_TRANS_SUP_WAIT )
1748   {
1749     ElaboTrans->TYPE = VPN_TRANS_IMMEDIATE;
1750   }
1751 /*\
1752   for ( ScanTrans  = DelPlace->TRANS_IN;
1753         ScanTrans != (chain_list *)0;
1754         ScanTrans  = ScanTrans->NEXT )
1755   {
1756     VpnArc   = GetVpnArc( ScanTrans );
1757     VpnTrans = GetVpnArcSourceTrans( VpnArc );
1758 
1759     addvpnarctrans( VpnFigure, VpnTrans, VpnPlace );
1760   }
1761 
1762   delvpntrans( VpnFigure, ElaboTrans );
1763   delvpnplace( VpnFigure, ElaboPlace );
1764 
1765   if ( IsVasyDebugLevel1() )
1766   {
1767     VasyDebugSaveVpnFig( VpnFigure );
1768   }
1769 \*/
1770 /*
1771 **  Start elaboration from the first process place
1772 */
1773   VasySimulateVpnPlace( VpnFigure, VpnProc, VpnPlace );
1774 
1775   if ( IsVasyDebugLevel0() )
1776   {
1777     VasyPrintf( stdout, "  <-- VasySimulateVpnProc %s\n", VpnProc->NAME );
1778   }
1779 }
1780