ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
wlcReadVer.c
Go to the documentation of this file.
1
20
21#include "wlc.h"
22
24
25
29
30// Word-level Verilog file parser
31#define WLV_PRS_MAX_LINE 10000
32
33typedef struct Wlc_Prs_t_ Wlc_Prs_t;
52
53static inline int Wlc_PrsOffset( Wlc_Prs_t * p, char * pStr ) { return pStr - p->pBuffer; }
54static inline char * Wlc_PrsStr( Wlc_Prs_t * p, int iOffset ) { return p->pBuffer + iOffset; }
55static inline int Wlc_PrsStrCmp( char * pStr, char * pWhat ) { return !strncmp( pStr, pWhat, strlen(pWhat)); }
56
57#define Wlc_PrsForEachLine( p, pLine, i ) \
58 for ( i = 0; (i < Vec_IntSize((p)->vStarts)) && ((pLine) = Wlc_PrsStr(p, Vec_IntEntry((p)->vStarts, i))); i++ )
59#define Wlc_PrsForEachLineStart( p, pLine, i, Start ) \
60 for ( i = Start; (i < Vec_IntSize((p)->vStarts)) && ((pLine) = Wlc_PrsStr(p, Vec_IntEntry((p)->vStarts, i))); i++ )
61
62
66
67
79Wlc_Prs_t * Wlc_PrsStart( char * pFileName, char * pStr )
80{
81 Wlc_Prs_t * p;
82 if ( pFileName && !Extra_FileCheck( pFileName ) )
83 return NULL;
84 p = ABC_CALLOC( Wlc_Prs_t, 1 );
85 p->pFileName = pFileName;
86 p->pBuffer = pStr ? Abc_UtilStrsav(pStr) : Extra_FileReadContents( pFileName );
87 p->nFileSize = strlen(p->pBuffer); assert( p->nFileSize > 0 );
88 p->vLines = Vec_IntAlloc( p->nFileSize / 50 );
89 p->vStarts = Vec_IntAlloc( p->nFileSize / 50 );
90 p->vFanins = Vec_IntAlloc( 100 );
91 p->vTables = Vec_PtrAlloc( 1000 );
92 p->pMemTable = Mem_FlexStart();
93 return p;
94}
96{
97 if ( p->pNtk )
98 Wlc_NtkFree( p->pNtk );
99 if ( p->pMemTable )
100 Mem_FlexStop( p->pMemTable, 0 );
101 Vec_StrFreeP( &p->vPoPairs );
102 Vec_PtrFreeP( &p->vTables );
103 Vec_IntFree( p->vLines );
104 Vec_IntFree( p->vStarts );
105 Vec_IntFree( p->vFanins );
106 ABC_FREE( p->pBuffer );
107 ABC_FREE( p );
108}
109
121int Wlc_PrsFindLine( Wlc_Prs_t * p, char * pCur )
122{
123 int Entry, iLine = 0;
124 Vec_IntForEachEntry( p->vLines, Entry, iLine )
125 if ( Entry > pCur - p->pBuffer )
126 return iLine + 1;
127 return -1;
128}
129int Wlc_PrsWriteErrorMessage( Wlc_Prs_t * p, char * pCur, const char * format, ... )
130{
131 char * pMessage;
132 // derive message
133 va_list args;
134 va_start( args, format );
135 pMessage = vnsprintf( format, args );
136 va_end( args );
137 // print messsage
138 assert( strlen(pMessage) < WLV_PRS_MAX_LINE - 100 );
139 assert( p->sError[0] == 0 );
140 if ( pCur == NULL ) // the line number is not given
141 sprintf( p->sError, "%s: %s\n", p->pFileName, pMessage );
142 else // print the error message with the line number
143 {
144 int iLine = Wlc_PrsFindLine( p, pCur );
145 sprintf( p->sError, "%s (line %d): %s\n", p->pFileName, iLine, pMessage );
146 }
147 ABC_FREE( pMessage );
148 return 0;
149}
151{
152 if ( p->sError[0] == 0 )
153 return;
154 fprintf( stdout, "%s", p->sError );
155}
156
168static inline int Wlc_PrsIsDigit( char * pStr )
169{
170 return (pStr[0] >= '0' && pStr[0] <= '9');
171}
172static inline int Wlc_PrsIsChar( char * pStr )
173{
174 return (pStr[0] >= 'a' && pStr[0] <= 'z') ||
175 (pStr[0] >= 'A' && pStr[0] <= 'Z') ||
176 (pStr[0] >= '0' && pStr[0] <= '9') ||
177 pStr[0] == '_' || pStr[0] == '$' || pStr[0] == '\\';
178}
179static inline char * Wlc_PrsSkipSpaces( char * pStr )
180{
181 while ( *pStr && *pStr == ' ' )
182 pStr++;
183 return pStr;
184}
185static inline char * Wlc_PrsFindSymbol( char * pStr, char Symb )
186{
187 int fNotName = 1;
188 for ( ; *pStr; pStr++ )
189 {
190 if ( fNotName && *pStr == Symb )
191 return pStr;
192 if ( pStr[0] == '\\' )
193 fNotName = 0;
194 else if ( !fNotName && *pStr == ' ' )
195 fNotName = 1;
196 }
197 return NULL;
198}
199static inline char * Wlc_PrsFindSymbolTwo( char * pStr, char Symb, char Symb2 )
200{
201 for ( ; pStr[1]; pStr++ )
202 if ( pStr[0] == Symb && pStr[1] == Symb2 )
203 return pStr;
204 return NULL;
205}
206static inline char * Wlc_PrsFindClosingParenthesis( char * pStr, char Open, char Close )
207{
208 int Counter = 0;
209 int fNotName = 1;
210 assert( *pStr == Open );
211 for ( ; *pStr; pStr++ )
212 {
213 if ( fNotName )
214 {
215 if ( *pStr == Open )
216 Counter++;
217 if ( *pStr == Close )
218 Counter--;
219 if ( Counter == 0 )
220 return pStr;
221 }
222 if ( *pStr == '\\' )
223 fNotName = 0;
224 else if ( !fNotName && *pStr == ' ' )
225 fNotName = 1;
226 }
227 return NULL;
228}
230{
231 int fSpecifyFound = 0;
232 char * pCur, * pNext, * pEnd = p->pBuffer + p->nFileSize;
233 for ( pCur = p->pBuffer; pCur < pEnd; pCur++ )
234 {
235 // regular comment (//)
236 if ( *pCur == '/' && pCur[1] == '/' )
237 {
238 if ( pCur + 5 < pEnd && pCur[2] == 'a' && pCur[3] == 'b' && pCur[4] == 'c' && pCur[5] == '2' )
239 pCur[0] = pCur[1] = pCur[2] = pCur[3] = pCur[4] = pCur[5] = ' ';
240 else if ( !strncmp(pCur + 3, "Pair:", 5) )
241 {
242 if ( p->vPoPairs == NULL )
243 p->vPoPairs = Vec_StrAlloc( 100 );
244 for ( pNext = pCur + 9; *pNext != '\n'; pNext++ )
245 {
246 if ( *pNext == ' ' )
247 Vec_StrPush( p->vPoPairs, '\0' );
248 else if ( *pNext != '\r' )
249 Vec_StrPush( p->vPoPairs, *pNext );
250 }
251 if ( Vec_StrEntryLast(p->vPoPairs) != 0 )
252 Vec_StrPush(p->vPoPairs, 0);
253 }
254 else
255 {
256 pNext = Wlc_PrsFindSymbol( pCur, '\n' );
257 if ( pNext == NULL )
258 return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find end-of-line after symbols \"//\"." );
259 for ( ; pCur < pNext; pCur++ )
260 *pCur = ' ';
261 }
262 }
263 // skip preprocessor directive (`timescale, `celldefine, etc)
264 else if ( *pCur == '`' )
265 {
266 pNext = Wlc_PrsFindSymbol( pCur, '\n' );
267 if ( pNext == NULL )
268 return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find end-of-line after symbols \"`\"." );
269 for ( ; pCur < pNext; pCur++ )
270 *pCur = ' ';
271 }
272 // regular comment (/* ... */)
273 else if ( *pCur == '/' && pCur[1] == '*' )
274 {
275 pNext = Wlc_PrsFindSymbolTwo( pCur, '*', '/' );
276 if ( pNext == NULL )
277 return Wlc_PrsWriteErrorMessage( p, pCur, "Cannot find symbols \"*/\" after symbols \"/*\"." );
278 // overwrite comment
279 for ( ; pCur < pNext + 2; pCur++ )
280 *pCur = ' ';
281 }
282 // 'specify' treated as comments
283 else if ( *pCur == 's' && pCur[1] == 'p' && pCur[2] == 'e' && !strncmp(pCur, "specify", 7) )
284 {
285 for ( pNext = pCur; pNext < pEnd - 10; pNext++ )
286 if ( *pNext == 'e' && pNext[1] == 'n' && pNext[2] == 'd' && !strncmp(pNext, "endspecify", 10) )
287 {
288 // overwrite comment
289 for ( ; pCur < pNext + 10; pCur++ )
290 *pCur = ' ';
291 if ( fSpecifyFound == 0 )
292 Abc_Print( 0, "Ignoring specify/endspecify directives.\n" );
293 fSpecifyFound = 1;
294 break;
295 }
296 }
297 // insert semicolons
298 else if ( *pCur == 'e' && pCur[1] == 'n' && pCur[2] == 'd' && !strncmp(pCur, "endmodule", 9) )
299 pCur[strlen("endmodule")] = ';';
300 // overwrite end-of-lines with spaces (less checking to do later on)
301 if ( *pCur == '\n' || *pCur == '\r' || *pCur == '\t' )
302 *pCur = ' ';
303 }
304 return 1;
305}
307{
308 int fPrettyPrint = 0;
309 int fNotName = 1;
310 char * pTemp, * pPrev, * pThis;
311 // collect info about lines
312 assert( Vec_IntSize(p->vLines) == 0 );
313 for ( pTemp = p->pBuffer; *pTemp; pTemp++ )
314 if ( *pTemp == '\n' )
315 Vec_IntPush( p->vLines, pTemp - p->pBuffer );
316 // delete comments and insert breaks
317 if ( !Wlc_PrsRemoveComments( p ) )
318 return 0;
319 // collect info about breaks
320 assert( Vec_IntSize(p->vStarts) == 0 );
321 for ( pPrev = pThis = p->pBuffer; *pThis; pThis++ )
322 {
323 if ( fNotName && *pThis == ';' )
324 {
325 *pThis = 0;
326 Vec_IntPush( p->vStarts, Wlc_PrsOffset(p, Wlc_PrsSkipSpaces(pPrev)) );
327 pPrev = pThis + 1;
328 }
329 if ( *pThis == '\\' )
330 fNotName = 0;
331 else if ( !fNotName && *pThis == ' ' )
332 fNotName = 1;
333 }
334
335 if ( fPrettyPrint )
336 {
337 int i, k;
338 // print the line types
339 Wlc_PrsForEachLine( p, pTemp, i )
340 {
341 if ( Wlc_PrsStrCmp( pTemp, "module" ) )
342 printf( "\n" );
343 if ( !Wlc_PrsStrCmp( pTemp, "module" ) && !Wlc_PrsStrCmp( pTemp, "endmodule" ) )
344 printf( " " );
345 printf( "%c", pTemp[0] );
346 for ( k = 1; pTemp[k]; k++ )
347 if ( pTemp[k] != ' ' || pTemp[k-1] != ' ' )
348 printf( "%c", pTemp[k] );
349 printf( ";\n" );
350 }
351/*
352 // print the line types
353 Wlc_PrsForEachLine( p, pTemp, i )
354 {
355 int k;
356 if ( !Wlc_PrsStrCmp( pTemp, "module" ) )
357 continue;
358 printf( "%3d : ", i );
359 for ( k = 0; k < 40; k++ )
360 printf( "%c", pTemp[k] ? pTemp[k] : ' ' );
361 printf( "\n" );
362 }
363*/
364 }
365 return 1;
366}
367
379char * Wlc_PrsStrtok( char * s, const char * delim )
380{
381 const char *spanp;
382 int c, sc;
383 char *tok;
384 static char *last;
385 if (s == NULL && (s = last) == NULL)
386 return NULL;
387 // skip leading delimiters
388cont:
389 c = *s++;
390 for (spanp = delim; (sc = *spanp++) != 0;)
391 if (c == sc)
392 goto cont;
393 if (c == 0) // no non-delimiter characters
394 return (last = NULL);
395// tok = s - 1;
396 if ( c != '\\' )
397 tok = s - 1;
398 else
399 tok = s - 1;
400 // go back to the first non-delimiter character
401 s--;
402 // find the token
403 for (;;)
404 {
405 c = *s++;
406 if ( c == '\\' ) // skip blind characters
407 {
408 while ( c != ' ' )
409 c = *s++;
410 c = *s++;
411 }
412 spanp = delim;
413 do {
414 if ((sc = *spanp++) == c)
415 {
416 if (c == 0)
417 s = NULL;
418 else
419 s[-1] = 0;
420 last = s;
421 return (tok);
422 }
423 } while (sc != 0);
424 }
425 // not reached
426 return NULL;
427}
428
441{
442 Wlc_Obj_t * pObj;
443 int i, k, Value, * pInits;
444 char * pResult;
445 Vec_Str_t * vStr = Vec_StrAlloc( 1000 );
446 Vec_IntForEachEntry( p->vInits, Value, i )
447 {
448 if ( Value < 0 )
449 {
450 for ( k = 0; k < -Value; k++ )
451 Vec_StrPush( vStr, '0' );
452 continue;
453 }
454 pObj = Wlc_NtkObj( p, Value );
455 Value = Wlc_ObjRange(pObj);
456 while ( pObj->Type == WLC_OBJ_BUF )
457 pObj = Wlc_NtkObj( p, Wlc_ObjFaninId0(pObj) );
458 pInits = (pObj->Type == WLC_OBJ_CONST && !pObj->fXConst) ? Wlc_ObjConstValue(pObj) : NULL;
459 for ( k = 0; k < Abc_MinInt(Value, Wlc_ObjRange(pObj)); k++ )
460 Vec_StrPush( vStr, (char)(pInits ? '0' + Abc_InfoHasBit((unsigned *)pInits, k) : 'x') );
461 // extend values with zero, in case the init value signal has different range compared to constant used
462 for ( ; k < Value; k++ )
463 Vec_StrPush( vStr, '0' );
464 // update vInits to contain either number of values or PI index
465 Vec_IntWriteEntry( p->vInits, i, (pInits || pObj->fXConst) ? -Value : Wlc_ObjCiId(pObj) );
466 }
467 Vec_StrPush( vStr, '\0' );
468 pResult = Vec_StrReleaseArray( vStr );
469 Vec_StrFree( vStr );
470 return pResult;
471}
472
485{
486 Wlc_Obj_t * pObj = Wlc_NtkObj( p, NameId );
487 int * pInits;
488 if ( Wlc_ObjRange(pObj) != 1 )
489 return 0;
490 while ( pObj->Type == WLC_OBJ_BUF )
491 pObj = Wlc_NtkObj( p, Wlc_ObjFaninId0(pObj) );
492 if ( pObj->Type != WLC_OBJ_CONST )
493 return 0;
494 pInits = Wlc_ObjConstValue(pObj);
495 return Abc_InfoHasBit((unsigned *)pInits, 0) == 0;
496}
497
498
510static inline char * Wlc_PrsFindRange( char * pStr, int * End, int * Beg )
511{
512 *End = *Beg = 0;
513 pStr = Wlc_PrsSkipSpaces( pStr );
514 if ( pStr[0] != '[' )
515 return pStr;
516 pStr = Wlc_PrsSkipSpaces( pStr+1 );
517 if ( !Wlc_PrsIsDigit(pStr) && pStr[0] != '-' )
518 return NULL;
519 *End = *Beg = atoi( pStr );
520 if ( Wlc_PrsFindSymbol( pStr, ':' ) == NULL )
521 {
522 pStr = Wlc_PrsFindSymbol( pStr, ']' );
523 if ( pStr == NULL )
524 return NULL;
525 }
526 else
527 {
528 pStr = Wlc_PrsFindSymbol( pStr, ':' );
529 pStr = Wlc_PrsSkipSpaces( pStr+1 );
530 if ( !Wlc_PrsIsDigit(pStr) && pStr[0] != '-' )
531 return NULL;
532 *Beg = atoi( pStr );
533 pStr = Wlc_PrsFindSymbol( pStr, ']' );
534 if ( pStr == NULL )
535 return NULL;
536 }
537 return pStr + 1;
538}
539static inline char * Wlc_PrsFindWord( char * pStr, char * pWord, int * fFound )
540{
541 *fFound = 0;
542 pStr = Wlc_PrsSkipSpaces( pStr );
543 if ( !Wlc_PrsStrCmp(pStr, pWord) )
544 return pStr;
545 *fFound = 1;
546 return pStr + strlen(pWord);
547}
548static inline char * Wlc_PrsFindName( char * pStr, char ** ppPlace )
549{
550 static char Buffer[WLV_PRS_MAX_LINE];
551 char * pThis = *ppPlace = Buffer;
552 int fNotName = 1, Count = 0;
553 pStr = Wlc_PrsSkipSpaces( pStr );
554 if ( !Wlc_PrsIsChar(pStr) )
555 return NULL;
556// while ( Wlc_PrsIsChar(pStr) )
557// *pThis++ = *pStr++;
558 while ( *pStr )
559 {
560 if ( fNotName && !Wlc_PrsIsChar(pStr) )
561 break;
562 if ( *pStr == '\\' )
563 {
564 Count++;
565 fNotName = 0;
566 }
567 else if ( !fNotName && *pStr == ' ' )
568 {
569 Count--;
570 if ( !Count )
571 fNotName = 1;
572 }
573 *pThis++ = *pStr++;
574 }
575 *pThis = 0;
576 return pStr;
577}
578static inline char * Wlc_PrsReadConstant( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins, int * pRange, int * pSigned, int * pXValue )
579{
580 int i, nDigits, nBits = atoi( pStr );
581 *pRange = -1;
582 *pSigned = 0;
583 *pXValue = 0;
584 pStr = Wlc_PrsSkipSpaces( pStr );
585 if ( Wlc_PrsFindSymbol( pStr, '\'' ) == NULL )
586 {
587 // handle decimal number
588 int Number = atoi( pStr );
589 *pRange = Abc_Base2Log( Number+1 );
590 assert( *pRange < 32 );
591 while ( Wlc_PrsIsDigit(pStr) )
592 pStr++;
593 Vec_IntFill( vFanins, 1, Number );
594 return pStr;
595 }
596 pStr = Wlc_PrsFindSymbol( pStr, '\'' );
597 if ( pStr[1] == 's' )
598 {
599 *pSigned = 1;
600 pStr++;
601 }
602 if ( pStr[1] == 'b' )
603 {
604 Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
605 for ( i = 0; i < nBits; i++ )
606 if ( pStr[2+i] == '1' )
607 Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), nBits-1-i );
608 else if ( pStr[2+i] != '0' )
609 return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Wrong digit in binary constant \"%c\".", pStr[2+i] );
610 *pRange = nBits;
611 pStr += 2 + nBits;
612 return pStr;
613 }
614 if ( pStr[1] != 'h' )
615 return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Expecting hexadecimal constant and not \"%c\".", pStr[1] );
616 *pXValue = (pStr[2] == 'x' || pStr[2] == 'X');
617 if ( *pXValue == 'X' )
618 *pXValue = 'x';
619 Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 );
620 nDigits = Abc_TtReadHexNumber( (word *)Vec_IntArray(vFanins), pStr+2 );
621 if ( nDigits != (nBits + 3)/4 )
622 {
623// return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "The length of a constant does not match." );
624// printf( "Warning: The length of a constant (%d hex digits) does not match the number of bits (%d).\n", nDigits, nBits );
625 }
626 *pRange = nBits;
627 pStr += 2;
628 while ( Wlc_PrsIsChar(pStr) )
629 pStr++;
630 return pStr;
631}
632static inline char * Wlc_PrsReadName( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins )
633{
634 int NameId, fFound, iObj;
635 pStr = Wlc_PrsSkipSpaces( pStr );
636 if ( Wlc_PrsIsDigit(pStr) )
637 {
638 char Buffer[100];
639 int Range, Signed, XValue = 0;
640 Vec_Int_t * vFanins = Vec_IntAlloc(0);
641 pStr = Wlc_PrsReadConstant( p, pStr, vFanins, &Range, &Signed, &XValue );
642 if ( pStr == NULL )
643 {
644 Vec_IntFree( vFanins );
645 return 0;
646 }
647 // create new node
648 iObj = Wlc_ObjAlloc( p->pNtk, WLC_OBJ_CONST, Signed, Range-1, 0 );
649 Wlc_ObjAddFanins( p->pNtk, Wlc_NtkObj(p->pNtk, iObj), vFanins );
650 Wlc_NtkObj(p->pNtk, iObj)->fXConst = XValue;
651 Vec_IntFree( vFanins );
652 // add node's name
653 sprintf( Buffer, "_c%d_", p->nConsts++ );
654 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, Buffer, &fFound );
655 if ( fFound )
656 return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is already used.", Buffer );
657 assert( iObj == NameId );
658 }
659 else
660 {
661 char * pName;
662 pStr = Wlc_PrsFindName( pStr, &pName );
663 if ( pStr == NULL )
664 return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in assign-statement." );
665 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
666 if ( !fFound )
667 return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is used but not declared.", pName );
668 }
669 Vec_IntPush( vFanins, NameId );
670 return Wlc_PrsSkipSpaces( pStr );
671}
672static inline int Wlc_PrsFindDefinition( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins, int * pXValue )
673{
674 char * pName;
675 int Type = WLC_OBJ_NONE;
676 int fRotating = 0;
677 Vec_IntClear( vFanins );
678 pStr = Wlc_PrsSkipSpaces( pStr );
679 if ( pStr[0] != '=' )
680 return 0;
681 pStr = Wlc_PrsSkipSpaces( pStr+1 );
682 if ( pStr[0] == '(' )
683 {
684 // consider rotating shifter
685 if ( Wlc_PrsFindSymbolTwo(pStr, '>', '>') && Wlc_PrsFindSymbolTwo(pStr, '<', '<') )
686 {
687 // THIS IS A HACK TO DETECT rotating shifters
688 char * pClose = Wlc_PrsFindClosingParenthesis( pStr, '(', ')' );
689 if ( pClose == NULL )
690 return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting closing parenthesis." );
691 *pStr = ' '; *pClose = 0;
692 pStr = Wlc_PrsSkipSpaces( pStr );
693 fRotating = 1;
694 }
695 else
696 {
697 char * pClose = Wlc_PrsFindClosingParenthesis( pStr, '(', ')' );
698 if ( pClose == NULL )
699 return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting closing parenthesis." );
700 *pStr = *pClose = ' ';
701 pStr = Wlc_PrsSkipSpaces( pStr );
702 }
703 }
704 if ( Wlc_PrsIsDigit(pStr) )
705 {
706 int Range, Signed;
707 pStr = Wlc_PrsReadConstant( p, pStr, vFanins, &Range, &Signed, pXValue );
708 if ( pStr == NULL )
709 return 0;
710 Type = WLC_OBJ_CONST;
711 }
712 else if ( pStr[0] == '!' || (pStr[0] == '~' && pStr[1] != '&' && pStr[1] != '|' && pStr[1] != '^') || pStr[0] == '@' || pStr[0] == '#' )
713 {
714 if ( pStr[0] == '!' )
715 Type = WLC_OBJ_LOGIC_NOT;
716 else if ( pStr[0] == '~' )
717 Type = WLC_OBJ_BIT_NOT;
718 else if ( pStr[0] == '@' )
719 Type = WLC_OBJ_ARI_SQRT;
720 else if ( pStr[0] == '#' )
721 Type = WLC_OBJ_ARI_SQUARE;
722 else assert( 0 );
723 // skip parentheses
724 pStr = Wlc_PrsSkipSpaces( pStr+1 );
725 if ( pStr[0] == '(' )
726 {
727 char * pClose = Wlc_PrsFindClosingParenthesis( pStr, '(', ')' );
728 if ( pClose == NULL )
729 return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting closing parenthesis." );
730 *pStr = *pClose = ' ';
731 }
732 if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) )
733 return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after !." );
734 }
735 else if ( pStr[0] == '-' ||
736 pStr[0] == '&' || pStr[0] == '|' || pStr[0] == '^' ||
737 (pStr[0] == '~' && pStr[1] == '&') ||
738 (pStr[0] == '~' && pStr[1] == '|') ||
739 (pStr[0] == '~' && pStr[1] == '^') )
740 {
741 int shift = 1;
742 if ( pStr[0] == '-' )
743 Type = WLC_OBJ_ARI_MINUS;
744 else if ( pStr[0] == '&' )
745 Type = WLC_OBJ_REDUCT_AND;
746 else if ( pStr[0] == '|' )
747 Type = WLC_OBJ_REDUCT_OR;
748 else if ( pStr[0] == '^' )
749 Type = WLC_OBJ_REDUCT_XOR;
750 else if ( pStr[0] == '~' && pStr[1] == '&' )
751 {Type = WLC_OBJ_REDUCT_NAND; shift = 2;}
752 else if ( pStr[0] == '~' && pStr[1] == '|' )
753 {Type = WLC_OBJ_REDUCT_NOR; shift = 2;}
754 else if ( pStr[0] == '~' && pStr[1] == '^' )
755 {Type = WLC_OBJ_REDUCT_NXOR; shift = 2;}
756 else assert( 0 );
757 if ( !(pStr = Wlc_PrsReadName(p, pStr+shift, vFanins)) )
758 return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name after a unary operator." );
759 }
760 else if ( pStr[0] == '{' )
761 {
762 // THIS IS A HACK TO DETECT zero padding AND sign extension
763 if ( Wlc_PrsFindSymbol(pStr+1, '{') )
764 {
765 if ( Wlc_PrsFindSymbol(pStr+1, '\'') )
766 Type = WLC_OBJ_BIT_ZEROPAD;
767 else
768 Type = WLC_OBJ_BIT_SIGNEXT;
769 pStr = Wlc_PrsFindSymbol(pStr+1, ',');
770 if ( pStr == NULL )
771 return Wlc_PrsWriteErrorMessage( p, pStr, "Expecting one comma in this line." );
772 if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
773 return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in sign-extension." );
774 pStr = Wlc_PrsSkipSpaces( pStr );
775 if ( pStr[0] != '}' )
776 return Wlc_PrsWriteErrorMessage( p, pStr, "There is no closing brace (})." );
777 }
778 else // concatenation
779 {
780 while ( 1 )
781 {
782 pStr = Wlc_PrsSkipSpaces( pStr+1 );
783 if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) )
784 return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in concatenation." );
785 if ( pStr[0] == '}' )
786 break;
787 if ( pStr[0] != ',' )
788 return Wlc_PrsWriteErrorMessage( p, pStr, "Expected comma (,) in this place." );
789 }
790 Type = WLC_OBJ_BIT_CONCAT;
791 }
792 assert( pStr[0] == '}' );
793 pStr++;
794 }
795 else
796 {
797 if ( !(pStr = Wlc_PrsReadName(p, pStr, vFanins)) )
798 return 0;
799 // get the next symbol
800 if ( pStr[0] == 0 )
801 Type = WLC_OBJ_BUF;
802 else if ( pStr[0] == '?' )
803 {
804 if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
805 return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in MUX." );
806 if ( pStr[0] != ':' )
807 return Wlc_PrsWriteErrorMessage( p, pStr, "MUX lacks the colon symbol (:)." );
808 if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
809 return Wlc_PrsWriteErrorMessage( p, pStr, "Cannot read name in MUX." );
810 assert( Vec_IntSize(vFanins) == 3 );
811 ABC_SWAP( int, Vec_IntArray(vFanins)[1], Vec_IntArray(vFanins)[2] );
812 Type = WLC_OBJ_MUX;
813 }
814 else if ( pStr[0] == '[' )
815 {
816 int End, Beg; char * pLine = pStr;
817 pStr = Wlc_PrsFindRange( pStr, &End, &Beg );
818 if ( pStr == NULL )
819 return Wlc_PrsWriteErrorMessage( p, pLine, "Non-standard range." );
820 Vec_IntPushTwo( vFanins, End, Beg );
821 Type = WLC_OBJ_BIT_SELECT;
822 }
823 else
824 {
825 if ( pStr[0] == '>' && pStr[1] == '>' && pStr[2] != '>' ) pStr += 2, Type = fRotating ? WLC_OBJ_ROTATE_R : WLC_OBJ_SHIFT_R;
826 else if ( pStr[0] == '>' && pStr[1] == '>' && pStr[2] == '>' ) pStr += 3, Type = WLC_OBJ_SHIFT_RA;
827 else if ( pStr[0] == '<' && pStr[1] == '<' && pStr[2] != '<' ) pStr += 2, Type = fRotating ? WLC_OBJ_ROTATE_L : WLC_OBJ_SHIFT_L;
828 else if ( pStr[0] == '<' && pStr[1] == '<' && pStr[2] == '<' ) pStr += 3, Type = WLC_OBJ_SHIFT_LA;
829 else if ( pStr[0] == '&' && pStr[1] != '&' ) pStr += 1, Type = WLC_OBJ_BIT_AND;
830 else if ( pStr[0] == '|' && pStr[1] != '|' ) pStr += 1, Type = WLC_OBJ_BIT_OR;
831 else if ( pStr[0] == '^' && pStr[1] != '^' ) pStr += 1, Type = WLC_OBJ_BIT_XOR;
832 else if ( pStr[0] == '~' && pStr[1] == '&' ) pStr += 2, Type = WLC_OBJ_BIT_NAND;
833 else if ( pStr[0] == '~' && pStr[1] == '|' ) pStr += 2, Type = WLC_OBJ_BIT_NOR;
834 else if ( pStr[0] == '~' && pStr[1] == '^' ) pStr += 2, Type = WLC_OBJ_BIT_NXOR;
835 else if ( pStr[0] == '=' && pStr[1] == '>' ) pStr += 2, Type = WLC_OBJ_LOGIC_IMPL;
836 else if ( pStr[0] == '&' && pStr[1] == '&' ) pStr += 2, Type = WLC_OBJ_LOGIC_AND;
837 else if ( pStr[0] == '|' && pStr[1] == '|' ) pStr += 2, Type = WLC_OBJ_LOGIC_OR;
838 else if ( pStr[0] == '^' && pStr[1] == '^' ) pStr += 2, Type = WLC_OBJ_LOGIC_XOR;
839 else if ( pStr[0] == '=' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_EQU;
840 else if ( pStr[0] == '!' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_NOTEQU;
841 else if ( pStr[0] == '<' && pStr[1] != '=' ) pStr += 1, Type = WLC_OBJ_COMP_LESS;
842 else if ( pStr[0] == '>' && pStr[1] != '=' ) pStr += 1, Type = WLC_OBJ_COMP_MORE;
843 else if ( pStr[0] == '<' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_LESSEQU;
844 else if ( pStr[0] == '>' && pStr[1] == '=' ) pStr += 2, Type = WLC_OBJ_COMP_MOREEQU;
845 else if ( pStr[0] == '+' ) pStr += 1, Type = WLC_OBJ_ARI_ADD;
846 else if ( pStr[0] == '-' ) pStr += 1, Type = WLC_OBJ_ARI_SUB;
847 else if ( pStr[0] == '*' && pStr[1] != '*' ) pStr += 1, Type = WLC_OBJ_ARI_MULTI;
848 else if ( pStr[0] == '/' ) pStr += 1, Type = WLC_OBJ_ARI_DIVIDE;
849 else if ( pStr[0] == '%' ) pStr += 1, Type = WLC_OBJ_ARI_REM;
850 else if ( pStr[0] == '*' && pStr[1] == '*' ) pStr += 2, Type = WLC_OBJ_ARI_POWER;
851 else return Wlc_PrsWriteErrorMessage( p, pStr, "Unsupported operation (%c).", pStr[0] );
852 if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
853 return 0;
854 pStr = Wlc_PrsSkipSpaces( pStr );
855 if ( Type == WLC_OBJ_ARI_ADD && pStr[0] == '+' )
856 {
857 if ( !(pStr = Wlc_PrsReadName(p, pStr+1, vFanins)) )
858 return 0;
859 pStr = Wlc_PrsSkipSpaces( pStr );
860 }
861 if ( pStr[0] )
862 printf( "Warning: Trailing symbols \"%s\" in line %d.\n", pStr, Wlc_PrsFindLine(p, pStr) );
863 }
864 }
865 // make sure there is nothing left there
866 if ( pStr )
867 {
868 pStr = Wlc_PrsFindName( pStr, &pName );
869 if ( pStr != NULL )
870 return Wlc_PrsWriteErrorMessage( p, pStr, "Name %s is left at the end of the line.", pName );
871 }
872 return Type;
873}
874int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )
875{
876 int fFound = 0, Type = WLC_OBJ_NONE, iObj; char * pLine;
877 int Signed = 0, Beg = 0, End = 0, NameId, fIsPo = 0;
878 if ( Wlc_PrsStrCmp( pStart, "input" ) )
879 pStart += strlen("input"), Type = WLC_OBJ_PI;
880 else if ( Wlc_PrsStrCmp( pStart, "output" ) )
881 pStart += strlen("output"), fIsPo = 1;
882 pStart = Wlc_PrsSkipSpaces( pStart );
883 if ( Wlc_PrsStrCmp( pStart, "wire" ) )
884 pStart += strlen("wire");
885 else if ( Wlc_PrsStrCmp( pStart, "reg" ) )
886 pStart += strlen("reg");
887 // read 'signed'
888 pStart = Wlc_PrsFindWord( pStart, "signed", &Signed );
889 // read range
890 pLine = pStart;
891 pStart = Wlc_PrsFindRange( pStart, &End, &Beg );
892 if ( pStart == NULL )
893 return Wlc_PrsWriteErrorMessage( p, pLine, "Non-standard range." );
894 if ( End != 0 && Beg != 0 )
895 {
896 if ( p->nNonZero[0]++ == 0 )
897 {
898 p->nNonZero[1] = End;
899 p->nNonZero[2] = Beg;
900 p->nNonZero[3] = Wlc_PrsFindLine(p, pStart);
901 }
902 }
903 if ( End < 0 || Beg < 0 )
904 {
905 if ( p->nNegative[0]++ == 0 )
906 {
907 p->nNegative[1] = End;
908 p->nNegative[2] = Beg;
909 p->nNegative[3] = Wlc_PrsFindLine(p, pStart);
910 }
911 }
912 if ( End < Beg )
913 {
914 if ( p->nReverse[0]++ == 0 )
915 {
916 p->nReverse[1] = End;
917 p->nReverse[2] = Beg;
918 p->nReverse[3] = Wlc_PrsFindLine(p, pStart);
919 }
920 }
921 while ( 1 )
922 {
923 char * pName; int XValue, TypeNew;
924 // read name
925 pStart = Wlc_PrsFindName( pStart, &pName );
926 if ( pStart == NULL )
927 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name in declaration." );
928 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
929 if ( fFound )
930 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is declared more than once.", pName );
931 iObj = Wlc_ObjAlloc( p->pNtk, Type, Signed, End, Beg );
932 if ( fIsPo ) Wlc_ObjSetCo( p->pNtk, Wlc_NtkObj(p->pNtk, iObj), 0 );
933 assert( iObj == NameId );
934 // check next definition
935 pStart = Wlc_PrsSkipSpaces( pStart );
936 if ( pStart[0] == ',' )
937 {
938 pStart++;
939 continue;
940 }
941 // check definition
942 TypeNew = Wlc_PrsFindDefinition( p, pStart, p->vFanins, &XValue );
943 if ( TypeNew )
944 {
945 Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, iObj );
946 Wlc_ObjUpdateType( p->pNtk, pObj, TypeNew );
947 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
948 pObj->fXConst = XValue;
949 }
950 break;
951 }
952 return 1;
953}
954int Wlc_PrsDerive( Wlc_Prs_t * p, int fInter )
955{
956 Wlc_Obj_t * pObj;
957 char * pStart, * pName;
958 int i;
959 // go through the directives
960 Wlc_PrsForEachLine( p, pStart, i )
961 {
962startword:
963 if ( Wlc_PrsStrCmp( pStart, "module" ) )
964 {
965 // get module name
966 pName = Wlc_PrsStrtok( pStart + strlen("module"), " \r\n\t(,)" );
967 if ( pName == NULL )
968 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read model name." );
969 // THIS IS A HACK to skip definitions of modules beginning with "CPL_"
970 if ( Wlc_PrsStrCmp( pName, "CPL_" ) )
971 {
972 while ( ++i < Vec_IntSize(p->vStarts) )
973 {
974 pStart = Wlc_PrsStr(p, Vec_IntEntry(p->vStarts, i));
975 pStart = strstr( pStart, "endmodule" );
976 if ( pStart != NULL )
977 break;
978 }
979 continue;
980 }
981 if ( Wlc_PrsStrCmp( pName, "table" ) )
982 {
983 // THIS IS A HACK to detect table module descriptions
984 int Width1 = -1, Width2 = -1;
985 int v, b, Value, nBits, nInts;
986 unsigned * pTable;
987 Vec_Int_t * vValues = Vec_IntAlloc( 256 );
988 Wlc_PrsForEachLineStart( p, pStart, i, i+1 )
989 {
990 if ( Wlc_PrsStrCmp( pStart, "endcase" ) )
991 break;
992 pStart = Wlc_PrsFindSymbol( pStart, '\'' );
993 if ( pStart == NULL )
994 continue;
995 Width1 = atoi(pStart-1);
996 pStart = Wlc_PrsFindSymbol( pStart+2, '\'' );
997 if ( pStart == NULL )
998 continue;
999 Width2 = atoi(pStart-1);
1000 Value = 0;
1001 Abc_TtReadHexNumber( (word *)&Value, pStart+2 );
1002 Vec_IntPush( vValues, Value );
1003 }
1004 //Vec_IntPrint( vValues );
1005 nBits = Abc_Base2Log( Vec_IntSize(vValues) );
1006 if ( Vec_IntSize(vValues) != (1 << nBits) )
1007 {
1008 Vec_IntFree( vValues );
1009 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read module \"%s\".", pName );
1010 }
1011 assert( Width1 == nBits );
1012 // create bitmap
1013 nInts = Abc_BitWordNum( Width2 * Vec_IntSize(vValues) );
1014 pTable = (unsigned *)Mem_FlexEntryFetch( p->pMemTable, nInts * sizeof(unsigned) );
1015 memset( pTable, 0, nInts * sizeof(unsigned) );
1016 Vec_IntForEachEntry( vValues, Value, v )
1017 for ( b = 0; b < Width2; b++ )
1018 if ( (Value >> b) & 1 )
1019 Abc_InfoSetBit( pTable, v * Width2 + b );
1020 Vec_PtrPush( p->vTables, pTable );
1021 Vec_IntFree( vValues );
1022 continue;
1023 }
1024 if ( p->pNtk != NULL )
1025 return Wlc_PrsWriteErrorMessage( p, pStart, "Network is already defined." );
1026 p->pNtk = Wlc_NtkAlloc( pName, Vec_IntSize(p->vStarts) );
1027 p->pNtk->pManName = Abc_NamStart( Vec_IntSize(p->vStarts), 20 );
1028 p->pNtk->pMemTable = p->pMemTable; p->pMemTable = NULL;
1029 p->pNtk->vTables = p->vTables; p->vTables = NULL;
1030 // read the argument definitions
1031 while ( (pName = Wlc_PrsStrtok( NULL, "(,)" )) )
1032 {
1033 pName = Wlc_PrsSkipSpaces( pName );
1034 if ( fInter && Wlc_PrsStrCmp( pName, "wire" ) )
1035 return 0;
1036 if ( Wlc_PrsStrCmp( pName, "input" ) || Wlc_PrsStrCmp( pName, "output" ) || Wlc_PrsStrCmp( pName, "wire" ) )
1037 {
1038 if ( !Wlc_PrsReadDeclaration( p, pName ) )
1039 return 0;
1040 }
1041 }
1042 }
1043 else if ( Wlc_PrsStrCmp( pStart, "endmodule" ) )
1044 {
1045 Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(p->pNtk) );
1046 Vec_IntAppend( &p->pNtk->vNameIds, vTemp );
1047 Vec_IntFree( vTemp );
1048 if ( p->pNtk->vInits )
1049 {
1050 // move FO/FI to be part of CI/CO
1051 assert( (Vec_IntSize(&p->pNtk->vFfs) & 1) == 0 );
1052 assert( Vec_IntSize(&p->pNtk->vFfs) == 2 * Vec_IntSize(p->pNtk->vInits) );
1053 Wlc_NtkForEachFf( p->pNtk, pObj, i )
1054 if ( i & 1 )
1055 Wlc_ObjSetCo( p->pNtk, pObj, 1 );
1056 else
1057 Wlc_ObjSetCi( p->pNtk, pObj );
1058 Vec_IntClear( &p->pNtk->vFfs );
1059 // convert init values into binary string
1060 //Vec_IntPrint( p->pNtk->vInits );
1061 p->pNtk->pInits = Wlc_PrsConvertInitValues( p->pNtk );
1062 //printf( "%s\n", p->pNtk->pInits );
1063 }
1064 if ( p->pNtk->vArsts && !p->pNtk->fAsyncRst )
1065 {
1066 int i, NameIdArst;
1067 Vec_IntForEachEntry( p->pNtk->vArsts, NameIdArst, i )
1068 {
1069 if ( Wlc_PrsCheckBitConst0(p->pNtk, NameIdArst) )
1070 continue;
1071 p->pNtk->fAsyncRst = 1;
1072 printf( "Detected async reset \"%s\".\n", Abc_NamStr(p->pNtk->pManName, NameIdArst) );
1073 break;
1074 }
1075 }
1076 if ( p->vPoPairs )
1077 {
1078 assert( Vec_StrEntryLast(p->vPoPairs) == 0 );
1079 Vec_StrPush( p->vPoPairs, 0 );
1080 pName = Vec_StrArray(p->vPoPairs);
1081 while ( *pName )
1082 {
1083 Wlc_NtkForEachPo( p->pNtk, pObj, i )
1084 if ( !strcmp(Wlc_ObjName(p->pNtk, Wlc_ObjId(p->pNtk, pObj)), pName) )
1085 {
1086 Vec_IntPush( &p->pNtk->vPoPairs, i );
1087 break;
1088 }
1089 assert( i < Wlc_NtkPoNum(p->pNtk) );
1090 pName += strlen(pName) + 1;
1091 }
1092 assert( Vec_IntSize(&p->pNtk->vPoPairs) % 2 == 0 );
1093 printf( "Finished parsing %d output pairs to be checked for equivalence.\n", Vec_IntSize(&p->pNtk->vPoPairs)/2 );
1094 }
1095 break;
1096 }
1097 // these are read as part of the interface
1098 else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" ) )
1099 {
1100 if ( fInter && (Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" )) )
1101 return 0;
1102 if ( !Wlc_PrsReadDeclaration( p, pStart ) )
1103 return 0;
1104 }
1105 else if ( Wlc_PrsStrCmp( pStart, "assign" ) )
1106 {
1107 int Type, NameId, fFound, XValue = 0;
1108 if ( fInter )
1109 return 0;
1110 pStart += strlen("assign");
1111 // read name
1112 pStart = Wlc_PrsFindName( pStart, &pName );
1113 if ( pStart == NULL )
1114 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after assign." );
1115 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1116 if ( !fFound )
1117 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1118 // read definition
1119 Type = Wlc_PrsFindDefinition( p, pStart, p->vFanins, &XValue );
1120 if ( Type )
1121 {
1122 pObj = Wlc_NtkObj( p->pNtk, NameId );
1123 Wlc_ObjUpdateType( p->pNtk, pObj, Type );
1124 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1125 pObj->fXConst = XValue;
1126 }
1127 else
1128 return 0;
1129 }
1130 else if ( Wlc_PrsStrCmp( pStart, "table" ) )
1131 {
1132 // THIS IS A HACK to detect tables
1133 int NameId, fFound, iTable = atoi( pStart + strlen("table") );
1134 // find opening
1135 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1136 if ( pStart == NULL )
1137 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." );
1138 // read input
1139 pStart = Wlc_PrsFindName( pStart+1, &pName );
1140 if ( pStart == NULL )
1141 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after assign." );
1142 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1143 if ( !fFound )
1144 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1145 // save inputs
1146 Vec_IntClear( p->vFanins );
1147 Vec_IntPush( p->vFanins, NameId );
1148 Vec_IntPush( p->vFanins, iTable );
1149 // find comma
1150 pStart = Wlc_PrsFindSymbol( pStart, ',' );
1151 if ( pStart == NULL )
1152 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." );
1153 // read output
1154 pStart = Wlc_PrsFindName( pStart+1, &pName );
1155 if ( pStart == NULL )
1156 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after assign." );
1157 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1158 if ( !fFound )
1159 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1160 pObj = Wlc_NtkObj( p->pNtk, NameId );
1161 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_TABLE );
1162 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1163 }
1164 else if ( Wlc_PrsStrCmp( pStart, "always" ) )
1165 {
1166 // THIS IS A HACK to detect always statement representing combinational MUX
1167 int NameId, NameIdOut = -1, fFound, nValues, fDefaultFound = 0;
1168 if ( fInter )
1169 return 0;
1170 // find control
1171 pStart = Wlc_PrsFindWord( pStart, "case", &fFound );
1172 if ( pStart == NULL )
1173 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read case statement." );
1174 // read the name
1175 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1176 if ( pStart == NULL )
1177 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." );
1178 pStart = Wlc_PrsFindSymbol( pStart+1, '(' );
1179 if ( pStart == NULL )
1180 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." );
1181 pStart = Wlc_PrsFindName( pStart+1, &pName );
1182 if ( pStart == NULL )
1183 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after case." );
1184 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1185 if ( !fFound )
1186 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1187 Vec_IntClear( p->vFanins );
1188 Vec_IntPush( p->vFanins, NameId );
1189 // read data inputs
1190 pObj = Wlc_NtkObj( p->pNtk, NameId );
1191 if ( pObj == NULL )
1192 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot find the object in case statement." );
1193 // remember the number of values
1194 nValues = (1 << Wlc_ObjRange(pObj));
1195 while ( 1 )
1196 {
1197 // find opening
1198 pStart = Wlc_PrsFindSymbol( pStart, ':' );
1199 if ( pStart == NULL )
1200 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot find colon in the case statement." );
1201 // find output name
1202 pStart = Wlc_PrsFindName( pStart+1, &pName );
1203 if ( pStart == NULL )
1204 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after case." );
1205 NameIdOut = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1206 if ( !fFound )
1207 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1208 // find equality
1209 pStart = Wlc_PrsFindSymbol( pStart, '=' );
1210 if ( pStart == NULL )
1211 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot find equality in the case statement." );
1212 // find input name
1213 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1214 pStart = Wlc_PrsReadName( p, pStart, p->vFanins );
1215 if ( pStart == NULL )
1216 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside case statement." );
1217 // consider default
1218 if ( fDefaultFound )
1219 {
1220 int EntryLast = Vec_IntEntryLast( p->vFanins );
1221 if (nValues != Vec_IntSize(p->vFanins)-2)
1222 Vec_IntFillExtra( p->vFanins, nValues + 1, EntryLast );
1223 else
1224 Vec_IntPop(p->vFanins);
1225 // get next line and check its opening character
1226 pStart = Wlc_PrsStr(p, Vec_IntEntry(p->vStarts, ++i));
1227 pStart = Wlc_PrsSkipSpaces( pStart );
1228 }
1229 else
1230 {
1231 // get next line and check its opening character
1232 pStart = Wlc_PrsStr(p, Vec_IntEntry(p->vStarts, ++i));
1233 pStart = Wlc_PrsSkipSpaces( pStart );
1234 if ( Wlc_PrsIsDigit(pStart) )
1235 continue;
1236 if ( Wlc_PrsStrCmp( pStart, "default" ) )
1237 {
1238 fDefaultFound = 1;
1239 continue;
1240 }
1241 }
1242 // find closing
1243 pStart = Wlc_PrsFindWord( pStart, "endcase", &fFound );
1244 if ( pStart == NULL )
1245 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read case statement." );
1246 // find closing
1247 pStart = Wlc_PrsFindWord( pStart, "end", &fFound );
1248 if ( pStart == NULL )
1249 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read case statement." );
1250 pStart = Wlc_PrsSkipSpaces( pStart );
1251 break;
1252 }
1253 // check range of the control
1254 if ( nValues < Vec_IntSize(p->vFanins) - 1 ) // may occur if default is not there
1255 {
1256 //return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName );
1257 printf( "Warning: The number of values in the case statement is wrong.\n" );
1258 Vec_IntShrink(p->vFanins,nValues+1);
1259 }
1260 else if ( nValues > Vec_IntSize(p->vFanins) - 1 )
1261 return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName );
1262 if ( Wlc_ObjRange(pObj) == 1 )
1263 {
1264// return Wlc_PrsWriteErrorMessage( p, pStart, "Always-statement with 1-bit control is not bit-blasted correctly.", pName );
1265 printf( "Warning: Case-statement with 1-bit control is treated as a 2:1 MUX (correct for unsigned signals only).\n" );
1266 }
1267 pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
1268 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_MUX );
1269 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1270 goto startword;
1271 }
1272 else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) )
1273 {
1274 int NameId = -1, NameIdIn = -1, NameIdOut = -1, fFound, nBits = 1, fFlopIn, fFlopOut;
1275 pStart += strlen("CPL_FF");
1276 if ( pStart[0] == '#' )
1277 nBits = atoi(pStart+1);
1278 // read names
1279 while ( 1 )
1280 {
1281 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1282 if ( pStart == NULL )
1283 break;
1284 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1285 if ( !p->pNtk->fAsyncRst && !strncmp(pStart, "arst", 4) && pStart[4] != 'v' )
1286 {
1287 int NameIdArst;
1288 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1289 if ( pStart == NULL )
1290 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1291 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1292 if ( Wlc_PrsIsDigit(pStart) )
1293 {
1294 int Range, Signed, XValue;
1295 Vec_Int_t * vFanins = Vec_IntAlloc( 100 );
1296 pStart = Wlc_PrsReadConstant( p, pStart, vFanins, &Range, &Signed, &XValue );
1297 if ( pStart && Vec_IntSize(vFanins) == 1 && Vec_IntEntry(vFanins, 0) == 0 )
1298 {
1299 Vec_IntFree( vFanins );
1300 continue;
1301 }
1302 printf( "Detected async reset.\n" );
1303 p->pNtk->fAsyncRst = 1;
1304 Vec_IntFree( vFanins );
1305 continue;
1306 }
1307 pStart = Wlc_PrsFindName( pStart, &pName );
1308 if ( pStart == NULL )
1309 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1310 NameIdArst = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1311 if ( p->pNtk->vArsts == NULL )
1312 p->pNtk->vArsts = Vec_IntAlloc( 100 );
1313 Vec_IntPushUnique( p->pNtk->vArsts, NameIdArst );
1314 continue;
1315 }
1316 if ( pStart[0] != 'd' && (pStart[0] != 'q' || pStart[1] == 'b') && strncmp(pStart, "arstval", 7) )
1317 continue;
1318 fFlopIn = (pStart[0] == 'd');
1319 fFlopOut = (pStart[0] == 'q');
1320 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1321 if ( pStart == NULL )
1322 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1323 pStart = Wlc_PrsFindName( pStart+1, &pName );
1324 if ( pStart == NULL )
1325 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1326 if ( fFlopIn )
1327 NameIdIn = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1328 else if ( fFlopOut )
1329 NameIdOut = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1330 else
1331 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1332 if ( !fFound )
1333 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1334 }
1335 if ( NameIdIn == -1 || NameIdOut == -1 )
1336 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." );
1337 // create flop output
1338 pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
1339 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FO );
1340 Vec_IntPush( &p->pNtk->vFfs, NameIdOut );
1341 //if ( nBits != Wlc_ObjRange(pObj) )
1342 // printf( "Warning! Flop output \"%s\" has bit-width (%d) that differs from the flop declaration (%d)\n", Abc_NamStr(p->pNtk->pManName, NameIdOut), Wlc_ObjRange(pObj), nBits );
1343 // create flop input
1344 pObj = Wlc_NtkObj( p->pNtk, NameIdIn );
1345 Vec_IntPush( &p->pNtk->vFfs, NameIdIn );
1346 //if ( nBits != Wlc_ObjRange(pObj) )
1347 // printf( "Warning! Flop input \"%s\" has bit-width (%d) that differs from the flop declaration (%d)\n", Abc_NamStr(p->pNtk->pManName, NameIdIn), Wlc_ObjRange(pObj), nBits );
1348 // save flop init value
1349 if ( NameId == -1 )
1350 printf( "Initial value of flop \"%s\" is not specified. Zero is assumed.\n", Abc_NamStr(p->pNtk->pManName, NameIdOut) );
1351 else
1352 {
1353 pObj = Wlc_NtkObj( p->pNtk, NameId );
1354 if ( nBits != Wlc_ObjRange(pObj) )
1355 printf( "Warning! Flop init signal \"%s\" bit-width (%d) is different from the flop declaration (%d)\n", Abc_NamStr(p->pNtk->pManName, NameId), Wlc_ObjRange(pObj), nBits );
1356 }
1357 if ( p->pNtk->vInits == NULL )
1358 p->pNtk->vInits = Vec_IntAlloc( 100 );
1359 Vec_IntPush( p->pNtk->vInits, NameId > 0 ? NameId : -nBits );
1360 // printf( "Created flop %s with range %d and init value %d (nameId = %d)\n",
1361 // Abc_NamStr(p->pNtk->pManName, NameIdOut), Wlc_ObjRange(pObj), nBits, NameId );
1362 }
1363 else if ( Wlc_PrsStrCmp( pStart, "ABC_DFFRSE" ) )
1364 {
1365 int NameId[10] = {0}, fFound, fFlopIn, fFlopClk, fFlopRst, fFlopSet, fFlopEna, fFlopAsync, fFlopSre, fFlopInit, fFlopOut;
1366 pStart += strlen("ABC_DFFRSE");
1367 while ( 1 )
1368 {
1369 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1370 if ( pStart == NULL )
1371 break;
1372 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1373 fFlopIn = (pStart[0] == 'd');
1374 fFlopClk = (pStart[0] == 'c');
1375 fFlopRst = (pStart[0] == 'r');
1376 fFlopSet = (pStart[0] == 's' && pStart[1] == 'e');
1377 fFlopEna = (pStart[0] == 'e');
1378 fFlopAsync = (pStart[0] == 'a');
1379 fFlopSre = (pStart[0] == 's' && pStart[1] == 'r');
1380 fFlopInit = (pStart[0] == 'i');
1381 fFlopOut = (pStart[0] == 'q');
1382 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1383 if ( pStart == NULL )
1384 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1385 pStart = Wlc_PrsFindName( pStart+1, &pName );
1386 if ( pStart == NULL )
1387 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1388 if ( fFlopIn )
1389 NameId[0] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1390 else if ( fFlopClk )
1391 NameId[1] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1392 else if ( fFlopRst )
1393 NameId[2] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1394 else if ( fFlopSet )
1395 NameId[3] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1396 else if ( fFlopEna )
1397 NameId[4] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1398 else if ( fFlopAsync )
1399 NameId[5] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1400 else if ( fFlopSre )
1401 NameId[6] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1402 else if ( fFlopInit )
1403 NameId[7] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1404 else if ( fFlopOut )
1405 NameId[8] = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1406 else
1407 assert( 0 );
1408 if ( !fFound )
1409 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1410 }
1411 if ( NameId[0] == -1 || NameId[7] == -1 )
1412 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." );
1413 // create output
1414 pObj = Wlc_NtkObj( p->pNtk, NameId[8] );
1415 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FF );
1416 Vec_IntClear( p->vFanins );
1417 Vec_IntPush( p->vFanins, NameId[0] );
1418 Vec_IntPush( p->vFanins, NameId[1] );
1419 Vec_IntPush( p->vFanins, NameId[2] );
1420 Vec_IntPush( p->vFanins, NameId[3] );
1421 Vec_IntPush( p->vFanins, NameId[4] );
1422 Vec_IntPush( p->vFanins, NameId[5] );
1423 Vec_IntPush( p->vFanins, NameId[6] );
1424 Vec_IntPush( p->vFanins, NameId[7] );
1425 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1426 }
1427 else if ( Wlc_PrsStrCmp( pStart, "ABC_DFF" ) )
1428 {
1429 int NameId = -1, NameIdIn = -1, NameIdOut = -1, fFound, nBits = 1, fFlopIn, fFlopOut;
1430 pStart += strlen("ABC_DFF");
1431 while ( 1 )
1432 {
1433 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1434 if ( pStart == NULL )
1435 break;
1436 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1437 fFlopIn = (pStart[0] == 'd');
1438 fFlopOut = (pStart[0] == 'q');
1439 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1440 if ( pStart == NULL )
1441 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1442 pStart = Wlc_PrsFindName( pStart+1, &pName );
1443 if ( pStart == NULL )
1444 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1445 if ( fFlopIn )
1446 NameIdIn = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1447 else if ( fFlopOut )
1448 NameIdOut = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1449 else
1450 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1451 if ( !fFound )
1452 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1453 }
1454 if ( NameIdIn == -1 || NameIdOut == -1 )
1455 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of flop input or flop output is missing." );
1456 // create flop output
1457 pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
1458 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_FO );
1459 Vec_IntPush( &p->pNtk->vFfs, NameIdOut );
1460 nBits = Wlc_ObjRange(Wlc_NtkObj(p->pNtk, NameIdOut));
1461 // create flop input
1462 pObj = Wlc_NtkObj( p->pNtk, NameIdIn );
1463 Vec_IntPush( &p->pNtk->vFfs, NameIdIn );
1464 // compare bit-width
1465 if ( Wlc_ObjRange(Wlc_NtkObj(p->pNtk, NameIdIn)) != nBits )
1466 printf( "Warning! Flop input \"%s\" bit-width (%d) is different from that of flop output (%d)\n",
1467 Abc_NamStr(p->pNtk->pManName, NameId), Wlc_ObjRange(Wlc_NtkObj(p->pNtk, NameIdIn)), nBits );
1468 // save flop init value
1469 if ( NameId == -1 )
1470 printf( "Initial value of flop \"%s\" is not specified. Zero is assumed.\n", Abc_NamStr(p->pNtk->pManName, NameIdOut) );
1471 else
1472 {
1473 if ( Wlc_ObjRange(Wlc_NtkObj(p->pNtk, NameId)) != nBits )
1474 printf( "Warning! Flop init signal \"%s\" bit-width (%d) is different from that of flop output (%d)\n",
1475 Abc_NamStr(p->pNtk->pManName, NameId), Wlc_ObjRange(Wlc_NtkObj(p->pNtk, NameId)), nBits );
1476 }
1477 if ( p->pNtk->vInits == NULL )
1478 p->pNtk->vInits = Vec_IntAlloc( 100 );
1479 Vec_IntPush( p->pNtk->vInits, NameId > 0 ? NameId : -Wlc_ObjRange(Wlc_NtkObj(p->pNtk, NameIdOut)) );
1480 // printf( "Created flop %s with range %d and init value %d (nameId = %d)\n",
1481 // Abc_NamStr(p->pNtk->pManName, NameIdOut), Wlc_ObjRange(pObj), nBits, NameId );
1482 p->pNtk->fEasyFfs = 1;
1483 }
1484 else if ( Wlc_PrsStrCmp( pStart, "CPL_MEM_" ) )
1485 {
1486 int * pNameId = NULL, NameOutput, NameMi = -1, NameMo = -1, NameAddr = -1, NameDi = -1, NameDo = -1, fFound, fRead = 1;
1487 pStart += strlen("CPL_MEM_");
1488 if ( pStart[0] == 'W' )
1489 fRead = 0;
1490 // read names
1491 while ( 1 )
1492 {
1493 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1494 if ( pStart == NULL )
1495 break;
1496 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1497 if ( !strncmp(pStart, "mem_data_in", 11) )
1498 pNameId = &NameMi;
1499 else if ( !strncmp(pStart, "data_in", 7) )
1500 pNameId = &NameDi;
1501 else if ( !strncmp(pStart, "data_out", 8) )
1502 pNameId = fRead ? &NameDo : &NameMo;
1503 else if ( !strncmp(pStart, "addr_in", 7) )
1504 pNameId = &NameAddr;
1505 else
1506 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name of the input/output port." );
1507 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1508 if ( pStart == NULL )
1509 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1510 pStart = Wlc_PrsFindName( pStart+1, &pName );
1511 if ( pStart == NULL )
1512 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1513 *pNameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1514 if ( !fFound )
1515 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1516 }
1517 if ( fRead && (NameMi == -1 || NameAddr == -1 || NameDo == -1) )
1518 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of one of signals of read port is missing." );
1519 if ( !fRead && (NameMi == -1 || NameAddr == -1 || NameDi == -1 || NameMo == -1) )
1520 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of one of signals of write port is missing." );
1521 // create output
1522 NameOutput = fRead ? NameDo : NameMo;
1523 pObj = Wlc_NtkObj( p->pNtk, NameOutput );
1524 Wlc_ObjUpdateType( p->pNtk, pObj, fRead ? WLC_OBJ_READ : WLC_OBJ_WRITE );
1525 Vec_IntClear( p->vFanins );
1526 Vec_IntPush( p->vFanins, NameMi );
1527 Vec_IntPush( p->vFanins, NameAddr );
1528 if ( !fRead )
1529 Vec_IntPush( p->vFanins, NameDi );
1530 //printf( "Memory %s ", fRead ? "Read" : "Write" ); printf( "Fanins: " ); Vec_IntPrint( p->vFanins );
1531 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1532 }
1533 else if ( Wlc_PrsStrCmp( pStart, "ABC_READ" ) )
1534 {
1535 int * pNameId = NULL, NameMemIn = -1, NameData = -1, NameAddr = -1, fFound;
1536 pStart += strlen("ABC_READ");
1537 while ( 1 )
1538 {
1539 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1540 if ( pStart == NULL )
1541 break;
1542 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1543 if ( !strncmp(pStart, "mem_in", 6) )
1544 pNameId = &NameMemIn;
1545 else if ( !strncmp(pStart, "addr", 4) )
1546 pNameId = &NameAddr;
1547 else if ( !strncmp(pStart, "data", 4) )
1548 pNameId = &NameData;
1549 else
1550 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name of the input/output port." );
1551 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1552 if ( pStart == NULL )
1553 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1554 pStart = Wlc_PrsFindName( pStart+1, &pName );
1555 if ( pStart == NULL )
1556 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1557 *pNameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1558 if ( !fFound )
1559 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1560 }
1561 if ( NameMemIn == -1 || NameAddr == -1 || NameData == -1 )
1562 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of one of signals of read port is missing." );
1563 // create output
1564 pObj = Wlc_NtkObj( p->pNtk, NameData );
1565 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_READ );
1566 Vec_IntClear( p->vFanins );
1567 Vec_IntPush( p->vFanins, NameMemIn );
1568 Vec_IntPush( p->vFanins, NameAddr );
1569 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1570 p->pNtk->fMemPorts = 1;
1571 }
1572 else if ( Wlc_PrsStrCmp( pStart, "ABC_WRITE" ) )
1573 {
1574 int * pNameId = NULL, NameMemIn = -1, NameMemOut = -1, NameData = -1, NameAddr = -1, fFound;
1575 pStart += strlen("ABC_WRITE");
1576 while ( 1 )
1577 {
1578 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1579 if ( pStart == NULL )
1580 break;
1581 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1582 if ( !strncmp(pStart, "mem_in", 6) )
1583 pNameId = &NameMemIn;
1584 else if ( !strncmp(pStart, "mem_out", 7) )
1585 pNameId = &NameMemOut;
1586 else if ( !strncmp(pStart, "data", 4) )
1587 pNameId = &NameData;
1588 else if ( !strncmp(pStart, "addr", 4) )
1589 pNameId = &NameAddr;
1590 else
1591 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name of the input/output port." );
1592 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1593 if ( pStart == NULL )
1594 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the flop description." );
1595 pStart = Wlc_PrsFindName( pStart+1, &pName );
1596 if ( pStart == NULL )
1597 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside flop description." );
1598 *pNameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1599 if ( !fFound )
1600 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1601 }
1602 if ( NameMemIn == -1 || NameAddr == -1 || NameData == -1 || NameMemOut == -1 )
1603 return Wlc_PrsWriteErrorMessage( p, pStart, "Name of one of signals of write port is missing." );
1604 // create output
1605 pObj = Wlc_NtkObj( p->pNtk, NameMemOut );
1606 Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_WRITE );
1607 Vec_IntClear( p->vFanins );
1608 Vec_IntPush( p->vFanins, NameMemIn );
1609 Vec_IntPush( p->vFanins, NameAddr );
1610 Vec_IntPush( p->vFanins, NameData );
1611 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1612 p->pNtk->fMemPorts = 1;
1613 }
1614 else if ( Wlc_PrsStrCmp( pStart, "CPL_RROT" ) || Wlc_PrsStrCmp( pStart, "CPL_LROT" ) )
1615 {
1616 // CPL_RROT #(128, 6) I_47479(.o ( E_46713 ) , .d ( E_46718 ) , .s ( E_46712 ) );
1617 int right_rotation = Wlc_PrsStrCmp( pStart, "CPL_RROT" );
1618 int NameId = -1, NameIdOut = -1, NameIdInD = -1, NameIdInS = -1, fFound, fRotInD, fRotInS, fRotOut;
1619 pStart += strlen("CPL_RROT");
1620
1621 // NOTE: no need to parse the parameter values
1622 //if ( pStart[0] == '#' )
1623
1624 // read names
1625 while ( 1 )
1626 {
1627 pStart = Wlc_PrsFindSymbol( pStart, '.' );
1628 if ( pStart == NULL )
1629 break;
1630 pStart = Wlc_PrsSkipSpaces( pStart+1 );
1631 if ( pStart[0] != 'o' && pStart[0] != 'd' && pStart[0] != 's')
1632 continue;
1633 fRotInD = (pStart[0] == 'd');
1634 fRotInS = (pStart[0] == 's');
1635 fRotOut = (pStart[0] == 'o');
1636 pStart = Wlc_PrsFindSymbol( pStart, '(' );
1637 if ( pStart == NULL )
1638 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read opening parenthesis in the rotation description." );
1639 pStart = Wlc_PrsFindName( pStart+1, &pName );
1640 if ( pStart == NULL )
1641 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside rotation description." );
1642 if ( fRotInD )
1643 NameIdInD = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1644 else if ( fRotInS )
1645 NameIdInS = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1646 else if ( fRotOut )
1647 NameIdOut = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1648 else
1649 NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound );
1650 if ( !fFound )
1651 return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName );
1652 }
1653 if ( NameIdOut == -1 || NameIdInD == -1 || NameIdInS == -1 )
1654 return Wlc_PrsWriteErrorMessage( p, pStart, "Some fields of CPL_ROT are missing." );
1655 // create rot output
1656 pObj = Wlc_NtkObj( p->pNtk, NameIdOut );
1657 Wlc_ObjUpdateType( p->pNtk, pObj, right_rotation ? WLC_OBJ_ROTATE_R : WLC_OBJ_ROTATE_L );
1658 Vec_IntClear( p->vFanins );
1659 Vec_IntPush( p->vFanins, NameIdInD );
1660 Vec_IntPush( p->vFanins, NameIdInS );
1661 Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );
1662 }
1663 else if ( pStart[0] == '(' && pStart[1] == '*' ) // skip comments
1664 {
1665 while ( *pStart++ != ')' );
1666 pStart = Wlc_PrsSkipSpaces( pStart );
1667 goto startword;
1668 }
1669 else if ( pStart[0] != '`' )
1670 {
1671 int iLine = Wlc_PrsFindLine(p, pStart);
1672 pStart = Wlc_PrsFindName( pStart, &pName );
1673 return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read line %d beginning with %s.", iLine, (!pName || !pName[0]) ? "\"?\"" : pName );
1674 }
1675 }
1676 if ( p->nNonZero[0] )
1677 {
1678 printf( "Warning: Input file contains %d objects with non-zero-based ranges.\n", p->nNonZero[0] );
1679 printf( "For example, signal with range [%d:%d] is declared in line %d.\n", p->nNonZero[1], p->nNonZero[2], p->nNonZero[3] );
1680 }
1681 if ( p->nNegative[0] )
1682 {
1683 printf( "Warning: Input file contains %d objects with negative ranges.\n", p->nNegative[0] );
1684 printf( "For example, signal with range [%d:%d] is declared in line %d.\n", p->nNegative[1], p->nNegative[2], p->nNegative[3] );
1685 }
1686 if ( p->nReverse[0] )
1687 {
1688 printf( "Warning: Input file contains %d objects with reversed ranges.\n", p->nReverse[0] );
1689 printf( "For example, signal with range [%d:%d] is declared in line %d.\n", p->nReverse[1], p->nReverse[2], p->nReverse[3] );
1690 }
1691 return 1;
1692}
1693Wlc_Ntk_t * Wlc_ReadVer( char * pFileName, char * pStr, int fInter )
1694{
1695 Wlc_Prs_t * p;
1696 Wlc_Ntk_t * pNtk = NULL;
1697 // either file name or string is given
1698 assert( (pFileName == NULL) != (pStr == NULL) );
1699 // start the parser
1700 p = Wlc_PrsStart( pFileName, pStr );
1701 if ( p == NULL )
1702 return NULL;
1703 // detect lines
1704 if ( !Wlc_PrsPrepare( p ) )
1705 goto finish;
1706 // parse models
1707 if ( !Wlc_PrsDerive( p, fInter ) )
1708 {
1709 if ( fInter )
1710 {
1711 printf( "Finished deriving interface for module \"%s\".\n", p->pNtk->pName );
1712 pNtk = p->pNtk; p->pNtk = NULL;
1713 pNtk->pSpec = Abc_UtilStrsav( pFileName );
1714 if ( Vec_IntSize(&pNtk->vNameIds) == 0 )
1715 {
1716 Vec_Int_t * vTemp = Vec_IntStartNatural( Wlc_NtkObjNumMax(pNtk) );
1717 pNtk->vNameIds = *vTemp, Vec_IntZero(vTemp);
1718 Vec_IntFree( vTemp );
1719 }
1720 return pNtk;
1721 }
1722 goto finish;
1723 }
1724 // derive topological order
1725 if ( p->pNtk )
1726 {
1727 Wlc_Obj_t * pObj; int i;
1728 Wlc_NtkForEachObj( p->pNtk, pObj, i )
1729 if ( pObj->Type == WLC_OBJ_FF )
1730 Vec_IntPush( &p->pNtk->vFfs2, Wlc_ObjId(p->pNtk, pObj) );
1731 pNtk = Wlc_NtkDupDfs( p->pNtk, 0, 1 );
1732 pNtk->pSpec = Abc_UtilStrsav( pFileName );
1733 }
1734finish:
1736 Wlc_PrsStop( p );
1737 return pNtk;
1738}
1739
1751void Io_ReadWordTest( char * pFileName )
1752{
1753 Gia_Man_t * pNew;
1754 Wlc_Ntk_t * pNtk = Wlc_ReadVer( pFileName, NULL, 0 );
1755 if ( pNtk == NULL )
1756 return;
1757 Wlc_WriteVer( pNtk, "test.v", 0, 0 );
1758
1759 pNew = Wlc_NtkBitBlast( pNtk, NULL );
1760 Gia_AigerWrite( pNew, "test.aig", 0, 0, 0 );
1761 Gia_ManStop( pNew );
1762
1763 Wlc_NtkFree( pNtk );
1764}
1765
1769
1770
1772
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
char * vnsprintf(const char *format, va_list args)
Definition utilFile.c:196
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
Cube * p
Definition exorList.c:222
int Extra_FileCheck(char *pFileName)
char * Extra_FileReadContents(char *pFileName)
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
void Gia_AigerWrite(Gia_Man_t *p, char *pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine)
Definition giaAiger.c:1595
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
Mem_Flex_t * Mem_FlexStart()
Definition mem.c:327
char * Mem_FlexEntryFetch(Mem_Flex_t *p, int nBytes)
Definition mem.c:388
void Mem_FlexStop(Mem_Flex_t *p, int fVerbose)
Definition mem.c:359
struct Mem_Flex_t_ Mem_Flex_t
Definition mem.h:34
char * pSpec
Definition wlc.h:139
Vec_Int_t vNameIds
Definition wlc.h:166
unsigned Type
Definition wlc.h:121
unsigned fXConst
Definition wlc.h:127
Mem_Flex_t * pMemTable
Definition wlcReadVer.c:43
char * pFileName
Definition wlcReadVer.c:37
int nFileSize
Definition wlcReadVer.c:36
Vec_Int_t * vStarts
Definition wlcReadVer.c:40
Vec_Str_t * vPoPairs
Definition wlcReadVer.c:45
int nNonZero[4]
Definition wlcReadVer.c:47
Wlc_Ntk_t * pNtk
Definition wlcReadVer.c:42
int nNegative[4]
Definition wlcReadVer.c:48
char sError[WLV_PRS_MAX_LINE]
Definition wlcReadVer.c:50
Vec_Ptr_t * vTables
Definition wlcReadVer.c:44
int nReverse[4]
Definition wlcReadVer.c:49
Vec_Int_t * vLines
Definition wlcReadVer.c:39
char * pBuffer
Definition wlcReadVer.c:38
Vec_Int_t * vFanins
Definition wlcReadVer.c:41
int Abc_NamStrFindOrAdd(Abc_Nam_t *p, char *pStr, int *pfFound)
Definition utilNam.c:453
Abc_Nam_t * Abc_NamStart(int nObjs, int nAveSize)
FUNCTION DEFINITIONS ///.
Definition utilNam.c:80
char * Abc_NamStr(Abc_Nam_t *p, int NameId)
Definition utilNam.c:555
#define assert(ex)
Definition util_old.h:213
int strncmp()
char * memset()
int strlen()
int strcmp()
char * sprintf()
char * strstr()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
void Io_ReadWordTest(char *pFileName)
#define WLV_PRS_MAX_LINE
DECLARATIONS ///.
Definition wlcReadVer.c:31
int Wlc_PrsPrepare(Wlc_Prs_t *p)
Definition wlcReadVer.c:306
char * Wlc_PrsStrtok(char *s, const char *delim)
Definition wlcReadVer.c:379
#define Wlc_PrsForEachLineStart(p, pLine, i, Start)
Definition wlcReadVer.c:59
int Wlc_PrsCheckBitConst0(Wlc_Ntk_t *p, int NameId)
Definition wlcReadVer.c:484
void Wlc_PrsPrintErrorMessage(Wlc_Prs_t *p)
Definition wlcReadVer.c:150
char * Wlc_PrsConvertInitValues(Wlc_Ntk_t *p)
Definition wlcReadVer.c:440
Wlc_Prs_t * Wlc_PrsStart(char *pFileName, char *pStr)
FUNCTION DEFINITIONS ///.
Definition wlcReadVer.c:79
struct Wlc_Prs_t_ Wlc_Prs_t
Definition wlcReadVer.c:33
int Wlc_PrsWriteErrorMessage(Wlc_Prs_t *p, char *pCur, const char *format,...)
Definition wlcReadVer.c:129
#define Wlc_PrsForEachLine(p, pLine, i)
Definition wlcReadVer.c:57
int Wlc_PrsFindLine(Wlc_Prs_t *p, char *pCur)
Definition wlcReadVer.c:121
void Wlc_PrsStop(Wlc_Prs_t *p)
Definition wlcReadVer.c:95
int Wlc_PrsRemoveComments(Wlc_Prs_t *p)
Definition wlcReadVer.c:229
int Wlc_PrsDerive(Wlc_Prs_t *p, int fInter)
Definition wlcReadVer.c:954
int Wlc_PrsReadDeclaration(Wlc_Prs_t *p, char *pStart)
Definition wlcReadVer.c:874
Wlc_Ntk_t * Wlc_ReadVer(char *pFileName, char *pStr, int fInter)
#define Wlc_NtkForEachPo(p, pPo, i)
Definition wlc.h:364
Gia_Man_t * Wlc_NtkBitBlast(Wlc_Ntk_t *p, Wlc_BstPar_t *pPars)
Definition wlcBlast.c:1349
int Wlc_ObjAlloc(Wlc_Ntk_t *p, int Type, int Signed, int End, int Beg)
Definition wlcNtk.c:199
void Wlc_ObjSetCo(Wlc_Ntk_t *p, Wlc_Obj_t *pObj, int fFlopInput)
Definition wlcNtk.c:188
Wlc_Ntk_t * Wlc_NtkDupDfs(Wlc_Ntk_t *p, int fMarked, int fSeq)
Definition wlcNtk.c:986
#define Wlc_NtkForEachFf(p, pFf, i)
Definition wlc.h:370
Wlc_Ntk_t * Wlc_NtkAlloc(char *pName, int nObjsAlloc)
Definition wlcNtk.c:152
void Wlc_NtkFree(Wlc_Ntk_t *p)
Definition wlcNtk.c:253
struct Wlc_Ntk_t_ Wlc_Ntk_t
Definition wlc.h:135
void Wlc_ObjAddFanins(Wlc_Ntk_t *p, Wlc_Obj_t *pObj, Vec_Int_t *vFanins)
Definition wlcNtk.c:240
void Wlc_ObjSetCi(Wlc_Ntk_t *p, Wlc_Obj_t *pObj)
Definition wlcNtk.c:168
void Wlc_WriteVer(Wlc_Ntk_t *p, char *pFileName, int fAddCos, int fNoFlops)
#define Wlc_NtkForEachObj(p, pObj, i)
MACRO DEFINITIONS ///.
Definition wlc.h:356
void Wlc_ObjUpdateType(Wlc_Ntk_t *p, Wlc_Obj_t *pObj, int Type)
Definition wlcNtk.c:233
char * Wlc_ObjName(Wlc_Ntk_t *p, int iObj)
Definition wlcNtk.c:225
@ WLC_OBJ_ARI_MULTI
Definition wlc.h:90
@ WLC_OBJ_READ
Definition wlc.h:99
@ WLC_OBJ_BIT_SIGNEXT
Definition wlc.h:70
@ WLC_OBJ_COMP_LESSEQU
Definition wlc.h:80
@ WLC_OBJ_LOGIC_XOR
Definition wlc.h:75
@ WLC_OBJ_WRITE
Definition wlc.h:100
@ WLC_OBJ_SHIFT_LA
Definition wlc.h:57
@ WLC_OBJ_BIT_ZEROPAD
Definition wlc.h:69
@ WLC_OBJ_COMP_MOREEQU
Definition wlc.h:81
@ WLC_OBJ_BUF
Definition wlc.h:52
@ WLC_OBJ_COMP_MORE
Definition wlc.h:79
@ WLC_OBJ_REDUCT_AND
Definition wlc.h:82
@ WLC_OBJ_ARI_POWER
Definition wlc.h:94
@ WLC_OBJ_ARI_REM
Definition wlc.h:92
@ WLC_OBJ_ARI_SUB
Definition wlc.h:89
@ WLC_OBJ_LOGIC_OR
Definition wlc.h:74
@ WLC_OBJ_LOGIC_AND
Definition wlc.h:73
@ WLC_OBJ_COMP_LESS
Definition wlc.h:78
@ WLC_OBJ_ARI_SQUARE
Definition wlc.h:97
@ WLC_OBJ_REDUCT_NOR
Definition wlc.h:86
@ WLC_OBJ_BIT_NOT
Definition wlc.h:60
@ WLC_OBJ_SHIFT_R
Definition wlc.h:54
@ WLC_OBJ_TABLE
Definition wlc.h:98
@ WLC_OBJ_BIT_AND
Definition wlc.h:61
@ WLC_OBJ_CONST
Definition wlc.h:51
@ WLC_OBJ_FO
Definition wlc.h:48
@ WLC_OBJ_ARI_DIVIDE
Definition wlc.h:91
@ WLC_OBJ_REDUCT_NAND
Definition wlc.h:85
@ WLC_OBJ_NONE
Definition wlc.h:45
@ WLC_OBJ_BIT_SELECT
Definition wlc.h:67
@ WLC_OBJ_REDUCT_OR
Definition wlc.h:83
@ WLC_OBJ_MUX
Definition wlc.h:53
@ WLC_OBJ_BIT_NAND
Definition wlc.h:64
@ WLC_OBJ_LOGIC_NOT
Definition wlc.h:71
@ WLC_OBJ_COMP_NOTEQU
Definition wlc.h:77
@ WLC_OBJ_PI
Definition wlc.h:46
@ WLC_OBJ_REDUCT_XOR
Definition wlc.h:84
@ WLC_OBJ_BIT_NOR
Definition wlc.h:65
@ WLC_OBJ_BIT_CONCAT
Definition wlc.h:68
@ WLC_OBJ_BIT_OR
Definition wlc.h:62
@ WLC_OBJ_BIT_XOR
Definition wlc.h:63
@ WLC_OBJ_ARI_MINUS
Definition wlc.h:95
@ WLC_OBJ_ARI_ADD
Definition wlc.h:88
@ WLC_OBJ_COMP_EQU
Definition wlc.h:76
@ WLC_OBJ_ARI_SQRT
Definition wlc.h:96
@ WLC_OBJ_LOGIC_IMPL
Definition wlc.h:72
@ WLC_OBJ_SHIFT_L
Definition wlc.h:56
@ WLC_OBJ_REDUCT_NXOR
Definition wlc.h:87
@ WLC_OBJ_BIT_NXOR
Definition wlc.h:66
@ WLC_OBJ_ROTATE_L
Definition wlc.h:59
@ WLC_OBJ_SHIFT_RA
Definition wlc.h:55
@ WLC_OBJ_FF
Definition wlc.h:50
@ WLC_OBJ_ROTATE_R
Definition wlc.h:58
struct Wlc_Obj_t_ Wlc_Obj_t
BASIC TYPES ///.
Definition wlc.h:118