bacReadVer.c 31.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
/**CFile****************************************************************

  FileName    [bacReadVer.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Hierarchical word-level netlist.]

  Synopsis    [BLIF writer.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - November 29, 2014.]

  Revision    [$Id: bacReadVer.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]

***********************************************************************/

#include "bac.h"
#include "bacPrs.h"

ABC_NAMESPACE_IMPL_START

////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

// Verilog keywords
typedef enum { 
    PRS_VER_NONE = 0,  // 0:  unused
    PRS_VER_INPUT,     // 1:  input
    PRS_VER_OUTPUT,    // 2:  output
    PRS_VER_INOUT,     // 3:  inout
    PRS_VER_WIRE,      // 4:  wire
    PRS_VER_MODULE,    // 5:  module
    PRS_VER_ASSIGN,    // 6:  assign
    PRS_VER_REG,       // 7:  reg
    PRS_VER_ALWAYS,    // 8:  always
    PRS_VER_DEFPARAM,  // 9:  always
    PRS_VER_BEGIN,     // 10: begin
    PRS_VER_END,       // 11: end
    PRS_VER_ENDMODULE, // 12: endmodule
    PRS_VER_UNKNOWN    // 13: unknown
} Bac_VerType_t;

static const char * s_VerTypes[PRS_VER_UNKNOWN+1] = {
    NULL,              // 0:  unused
    "input",           // 1:  input
    "output",          // 2:  output
    "inout",           // 3:  inout
    "wire",            // 4:  wire
    "module",          // 5:  module
    "assign",          // 6:  assign
    "reg",             // 7:  reg
    "always",          // 8:  always
    "defparam",        // 9:  defparam
    "begin",           // 10: begin
    "end",             // 11: end
    "endmodule",       // 12: endmodule
    NULL               // 13: unknown 
};

static inline void Psr_NtkAddVerilogDirectives( Psr_Man_t * p )
{
    int i;
    for ( i = 1; s_VerTypes[i]; i++ )
        Abc_NamStrFindOrAdd( p->pStrs, (char *)s_VerTypes[i],   NULL );
    assert( Abc_NamObjNumMax(p->pStrs) == i );
}


// character recognition 
static inline int Psr_CharIsSpace( char c )   { return (c == ' ' || c == '\t' || c == '\r' || c == '\n');                           }
static inline int Psr_CharIsDigit( char c )   { return (c >= '0' && c <= '9');                                                      }
static inline int Psr_CharIsDigitB( char c )  { return (c == '0' || c == '1'  || c == 'x' || c == 'z');                             }
static inline int Psr_CharIsDigitH( char c )  { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');  }
static inline int Psr_CharIsChar( char c )    { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');                            }
static inline int Psr_CharIsSymb1( char c )   { return Psr_CharIsChar(c) || c == '_';                                               }
static inline int Psr_CharIsSymb2( char c )   { return Psr_CharIsSymb1(c) || Psr_CharIsDigit(c) || c == '$';                        }

static inline int Psr_ManIsChar( Psr_Man_t * p, char c )    { return p->pCur[0] == c;                        }
static inline int Psr_ManIsChar1( Psr_Man_t * p, char c )   { return p->pCur[1] == c;                        }
static inline int Psr_ManIsDigit( Psr_Man_t * p )           { return Psr_CharIsDigit(*p->pCur);              }

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/

// collect predefined modules names
static const char * s_VerilogModules[100] = 
{
    "const0", // BAC_BOX_CF,  
    "const1", // BAC_BOX_CT,  
    "constX", // BAC_BOX_CX,  
    "constZ", // BAC_BOX_CZ,  
    "buf",    // BAC_BOX_BUF,  
    "not",    // BAC_BOX_INV,  
    "and",    // BAC_BOX_AND,  
    "nand",   // BAC_BOX_NAND, 
    "or",     // BAC_BOX_OR,   
    "nor",    // BAC_BOX_NOR,  
    "xor",    // BAC_BOX_XOR,  
    "xnor",   // BAC_BOX_XNOR, 
    "sharp",  // BAC_BOX_SHARP,
    "mux",    // BAC_BOX_MUX,  
    "maj",    // BAC_BOX_MAJ,  
    NULL
};
static const char * s_KnownModules[100] = 
{
    "VERIFIC_",
    "add_",                  
    "mult_",                 
    "div_",                  
    "mod_",                  
    "rem_",                  
    "shift_left_",           
    "shift_right_",          
    "rotate_left_",          
    "rotate_right_",         
    "reduce_and_",           
    "reduce_or_",            
    "reduce_xor_",           
    "reduce_nand_",          
    "reduce_nor_",           
    "reduce_xnor_",          
    "LessThan_",             
    "Mux_",                  
    "Select_",               
    "Decoder_",              
    "EnabledDecoder_",       
    "PrioSelect_",           
    "DualPortRam_",          
    "ReadPort_",             
    "WritePort_",            
    "ClockedWritePort_",     
    "lut",                   
    "and_",                  
    "or_",                   
    "xor_",                  
    "nand_",                 
    "nor_",                  
    "xnor_",                 
    "buf_",                  
    "inv_",                  
    "tri_",                  
    "sub_",                  
    "unary_minus_",          
    "equal_",                
    "not_equal_",            
    "mux_",                  
    "wide_mux_",             
    "wide_select_",          
    "wide_dff_",             
    "wide_dlatch_",          
    "wide_dffrs_",           
    "wide_dlatchrs_",        
    "wide_prio_select_",     
    "pow_",                  
    "PrioEncoder_",          
    "abs",                   
    NULL
};

// check if it is a Verilog predefined module
static inline int Psr_ManIsVerilogModule( Psr_Man_t * p, char * pName )
{
    int i;
    for ( i = 0; s_VerilogModules[i]; i++ )
        if ( !strcmp(pName, s_VerilogModules[i]) )
            return BAC_BOX_CF + i;
    return 0;
}
// check if it is a known module
static inline int Psr_ManIsKnownModule( Psr_Man_t * p, char * pName )
{
    int i;
    for ( i = 0; s_KnownModules[i]; i++ )
        if ( !strncmp(pName, s_KnownModules[i], strlen(s_KnownModules[i])) )
            return i;
    return 0;
}


/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/

// skips Verilog comments (returns 1 if some comments were skipped)
static inline int Psr_ManUtilSkipComments( Psr_Man_t * p )
{
    if ( !Psr_ManIsChar(p, '/') )
        return 0;
    if ( Psr_ManIsChar1(p, '/') )
    {
        for ( p->pCur += 2; p->pCur < p->pLimit; p->pCur++ )
            if ( Psr_ManIsChar(p, '\n') )
                { p->pCur++; return 1; }
    }
    else if ( Psr_ManIsChar1(p, '*') )
    {
        for ( p->pCur += 2; p->pCur < p->pLimit; p->pCur++ )
            if ( Psr_ManIsChar(p, '*') && Psr_ManIsChar1(p, '/') )
                { p->pCur++; p->pCur++; return 1; }
    }
    return 0;
}
static inline int Psr_ManUtilSkipName( Psr_Man_t * p )
{
    if ( !Psr_ManIsChar(p, '\\') )
        return 0;
    for ( p->pCur++; p->pCur < p->pLimit; p->pCur++ )
        if ( Psr_ManIsChar(p, ' ') )
            { p->pCur++; return 1; }
    return 0;
}

// skip any number of spaces and comments
static inline int Psr_ManUtilSkipSpaces( Psr_Man_t * p )
{
    while ( p->pCur < p->pLimit )
    {
        while ( Psr_CharIsSpace(*p->pCur) ) 
            p->pCur++;
        if ( !*p->pCur )
            return Psr_ManErrorSet(p, "Unexpectedly reached end-of-file.", 1);
        if ( !Psr_ManUtilSkipComments(p) )
            return 0;
    }
    return Psr_ManErrorSet(p, "Unexpectedly reached end-of-file.", 1);
}
// skip everything including comments until the given char
static inline int Psr_ManUtilSkipUntil( Psr_Man_t * p, char c )
{
    while ( p->pCur < p->pLimit )
    {
        if ( Psr_ManIsChar(p, c) )
            return 1;
        if ( Psr_ManUtilSkipComments(p) )
            continue;
        if ( Psr_ManUtilSkipName(p) )
            continue;
        p->pCur++;
    }
    return 0;
}
// skip everything including comments until the given word
static inline int Psr_ManUtilSkipUntilWord( Psr_Man_t * p, char * pWord )
{
    char * pPlace = strstr( p->pCur, pWord );
    if ( pPlace == NULL )  return 1;
    p->pCur = pPlace + strlen(pWord);
    return 0;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline int Psr_ManReadName( Psr_Man_t * p )
{
    char * pStart = p->pCur;
    if ( Psr_ManIsChar(p, '\\') ) // escaped name
    {
        pStart = ++p->pCur;
        while ( !Psr_ManIsChar(p, ' ') ) 
            p->pCur++;
    }    
    else if ( Psr_CharIsSymb1(*p->pCur) ) // simple name
    {
        p->pCur++;
        while ( Psr_CharIsSymb2(*p->pCur) ) 
            p->pCur++;
    }
    else 
        return 0;
    return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL );
}
static inline int Psr_ManReadNameList( Psr_Man_t * p, Vec_Int_t * vTemp, char LastSymb )
{
    Vec_IntClear( vTemp );
    while ( 1 )
    {
        int Item = Psr_ManReadName(p);
        if ( Item == 0 )                    return Psr_ManErrorSet(p, "Cannot read name in the list.", 0);
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 1.", 0);
        if ( Item == PRS_VER_WIRE  )
            continue;
        Vec_IntPush( vTemp, Item );
        if ( Psr_ManIsChar(p, LastSymb) )   break;
        if ( !Psr_ManIsChar(p, ',') )       return Psr_ManErrorSet(p, "Expecting comma in the list.", 0);
        p->pCur++;
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 2.", 0);
    }
    return 1;
}
static inline int Psr_ManReadConstant( Psr_Man_t * p )
{
    char * pStart = p->pCur;
    assert( Psr_ManIsDigit(p) );
    while ( Psr_ManIsDigit(p) ) 
        p->pCur++;
    if ( !Psr_ManIsChar(p, '\'') )          return Psr_ManErrorSet(p, "Cannot read constant.", 0);
    p->pCur++;
    if ( Psr_ManIsChar(p, 'b') )
    {
        p->pCur++;
        while ( Psr_CharIsDigitB(*p->pCur) ) 
        {
            if ( *p->pCur == '0' )
                p->pNtk->fHasC0s = 1;
            else if ( *p->pCur == '1' )
                p->pNtk->fHasC1s = 1;
            else if ( *p->pCur == 'x' )
                p->pNtk->fHasCXs = 1;
            else if ( *p->pCur == 'z' )
                p->pNtk->fHasCZs = 1;
            p->pCur++;
        }
    }
    else if ( Psr_ManIsChar(p, 'h') )
    {
        p->pCur++;
        p->pNtk->fHasC0s = 1;
        while ( Psr_CharIsDigitH(*p->pCur) ) 
        {
            if ( *p->pCur != '0' )
                p->pNtk->fHasC1s = 1;
            p->pCur++;
        }
    }
    else if ( Psr_ManIsChar(p, 'd') )
    {
        p->pCur++;
        p->pNtk->fHasC0s = 1;
        while ( Psr_ManIsDigit(p) ) 
        {
            if ( *p->pCur != '0' )
                p->pNtk->fHasC1s = 1;
            p->pCur++;
        }
    }
    else                                    return Psr_ManErrorSet(p, "Cannot read radix of constant.", 0);
    return Abc_NamStrFindOrAddLim( p->pStrs, pStart, p->pCur, NULL );
}
static inline int Psr_ManReadRange( Psr_Man_t * p )
{
    assert( Psr_ManIsChar(p, '[') );
    Vec_StrClear( &p->vCover );
    Vec_StrPush( &p->vCover, *p->pCur++ );
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 3.", 0);
    if ( !Psr_ManIsDigit(p) )               return Psr_ManErrorSet(p, "Cannot read digit in range specification.", 0);
    while ( Psr_ManIsDigit(p) )
        Vec_StrPush( &p->vCover, *p->pCur++ );
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 4.", 0);
    if ( Psr_ManIsChar(p, ':') )
    {
        Vec_StrPush( &p->vCover, *p->pCur++ );
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 5.", 0);
        if ( !Psr_ManIsDigit(p) )           return Psr_ManErrorSet(p, "Cannot read digit in range specification.", 0);
        while ( Psr_ManIsDigit(p) )
            Vec_StrPush( &p->vCover, *p->pCur++ );
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 6.", 0);
    }
    if ( !Psr_ManIsChar(p, ']') )           return Psr_ManErrorSet(p, "Cannot read closing brace in range specification.", 0);
    Vec_StrPush( &p->vCover, *p->pCur++ );
    Vec_StrPush( &p->vCover, '\0' );
    return Abc_NamStrFindOrAdd( p->pStrs, Vec_StrArray(&p->vCover), NULL );
}
static inline int Psr_ManReadConcat( Psr_Man_t * p, Vec_Int_t * vTemp2 )
{
    extern int Psr_ManReadSignalList( Psr_Man_t * p, Vec_Int_t * vTemp, char LastSymb, int fAddForm );
    assert( Psr_ManIsChar(p, '{') );
    p->pCur++;
    if ( !Psr_ManReadSignalList( p, vTemp2, '}', 0 ) ) return Psr_ManErrorSet(p, "Error number 7.", 0);
    // check final
    assert( Psr_ManIsChar(p, '}') );
    p->pCur++;
    // return special case
    assert( Vec_IntSize(vTemp2) > 0 );
    if ( Vec_IntSize(vTemp2) == 1 )
        return Vec_IntEntry(vTemp2, 0);
    return Abc_Var2Lit2( Psr_NtkAddConcat(p->pNtk, vTemp2), BAC_PRS_CONCAT );
}
static inline int Psr_ManReadSignal( Psr_Man_t * p )
{
    int Item;
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 8.", 0);
    if ( Psr_ManIsDigit(p) )
    {
        Item = Psr_ManReadConstant(p);
        if ( Item == 0 )                    return Psr_ManErrorSet(p, "Error number 9.", 0);
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 10.", 0);
        return Abc_Var2Lit2( Item, BAC_PRS_CONST );
    }
    if ( Psr_ManIsChar(p, '{') )
    {
        if ( p->fUsingTemp2 )               return Psr_ManErrorSet(p, "Cannot read nested concatenations.", 0);
        p->fUsingTemp2 = 1;
        Item = Psr_ManReadConcat(p, &p->vTemp2);
        p->fUsingTemp2 = 0;
        if ( Item == 0 )                    return Psr_ManErrorSet(p, "Error number 11.", 0);
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 12.", 0);
        return Item;
    }
    else
    {
        Item = Psr_ManReadName( p );
        if ( Item == 0 )                    return Psr_ManErrorSet(p, "Error number 13.", 0);    // was        return 1;                
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 14.", 0);
        if ( Psr_ManIsChar(p, '[') )
        {
            int Range = Psr_ManReadRange(p);
            if ( Range == 0 )               return Psr_ManErrorSet(p, "Error number 15.", 0);
            if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 16.", 0);
            return Abc_Var2Lit2( Psr_NtkAddSlice(p->pNtk, Item, Range), BAC_PRS_SLICE );
        }
        return Abc_Var2Lit2( Item, BAC_PRS_NAME );
    }
}
450
int Psr_ManReadSignalList( Psr_Man_t * p, Vec_Int_t * vTemp, char LastSymb, int fAddForm )
451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
{
    Vec_IntClear( vTemp );
    while ( 1 )
    {
        int Item = Psr_ManReadSignal(p);
        if ( Item == 0 )                    return Psr_ManErrorSet(p, "Cannot read signal in the list.", 0);
        if ( fAddForm )
            Vec_IntPush( vTemp, 0 );
        Vec_IntPush( vTemp, Item );
        if ( Psr_ManIsChar(p, LastSymb) )   break;
        if ( !Psr_ManIsChar(p, ',') )       return Psr_ManErrorSet(p, "Expecting comma in the list.", 0);
        p->pCur++;
    }
    return 1;
}
static inline int Psr_ManReadSignalList2( Psr_Man_t * p, Vec_Int_t * vTemp )
{
    int FormId, ActItem;
    Vec_IntClear( vTemp );
    assert( Psr_ManIsChar(p, '.') );
    while ( Psr_ManIsChar(p, '.') )
    {
        p->pCur++;
        FormId = Psr_ManReadName( p );
        if ( FormId == 0 )                  return Psr_ManErrorSet(p, "Cannot read formal name of the instance.", 0);
        if ( !Psr_ManIsChar(p, '(') )       return Psr_ManErrorSet(p, "Cannot read \"(\" in the instance.", 0);
        p->pCur++;
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 17.", 0);
        ActItem = Psr_ManReadSignal( p );
        if ( ActItem == 0 )                 return Psr_ManErrorSet(p, "Cannot read actual name of the instance.", 0);
        if ( !Psr_ManIsChar(p, ')') )       return Psr_ManErrorSet(p, "Cannot read \")\" in the instance.", 0);
        p->pCur++;
        Vec_IntPushTwo( vTemp, FormId, ActItem );
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 18.", 0);
        if ( Psr_ManIsChar(p, ')') )        break;
        if ( !Psr_ManIsChar(p, ',') )       return Psr_ManErrorSet(p, "Expecting comma in the instance.", 0);
        p->pCur++;
        if ( Psr_ManUtilSkipSpaces(p) )     return Psr_ManErrorSet(p, "Error number 19.", 0);
    }
    assert( Vec_IntSize(vTemp) > 0 );
    assert( Vec_IntSize(vTemp) % 2 == 0 );
    return 1;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
static inline int Psr_ManReadDeclaration( Psr_Man_t * p, int Type )
{
    int i, NameId, RangeId = 0;
    Vec_Int_t * vNames[4]  = { &p->pNtk->vInputs,  &p->pNtk->vOutputs,  &p->pNtk->vInouts,  &p->pNtk->vWires };
    Vec_Int_t * vNamesR[4] = { &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vInoutsR, &p->pNtk->vWiresR };
    assert( Type >= PRS_VER_INPUT && Type <= PRS_VER_WIRE );
    if ( Psr_ManUtilSkipSpaces(p) )                                   return Psr_ManErrorSet(p, "Error number 20.", 0);
    if ( Psr_ManIsChar(p, '[') && !(RangeId = Psr_ManReadRange(p)) )  return Psr_ManErrorSet(p, "Error number 21.", 0);
    if ( !Psr_ManReadNameList( p, &p->vTemp, ';' ) )                  return Psr_ManErrorSet(p, "Error number 22.", 0);
    Vec_IntForEachEntry( &p->vTemp, NameId, i )
    {
        Vec_IntPush( vNames[Type - PRS_VER_INPUT], NameId );
        Vec_IntPush( vNamesR[Type - PRS_VER_INPUT], RangeId );
        if ( Type < PRS_VER_WIRE )
            Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(NameId, Type) );
    }
    return 1;
}
static inline int Psr_ManReadAssign( Psr_Man_t * p )
{
    int OutItem, InItem, fCompl = 0, fCompl2 = 0, Oper = 0;
    // read output name
    OutItem = Psr_ManReadSignal( p );
    if ( OutItem == 0 )                     return Psr_ManErrorSet(p, "Cannot read output in assign-statement.", 0);
    if ( !Psr_ManIsChar(p, '=') )           return Psr_ManErrorSet(p, "Expecting \"=\" in assign-statement.", 0);
    p->pCur++;
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 23.", 0);
    if ( Psr_ManIsChar(p, '~') ) 
    { 
        fCompl = 1; 
        p->pCur++; 
    }
    // read first name
    InItem = Psr_ManReadSignal( p );
    if ( InItem == 0 )                      return Psr_ManErrorSet(p, "Cannot read first input name in the assign-statement.", 0);
    Vec_IntClear( &p->vTemp );
    Vec_IntPush( &p->vTemp, 0 );
    Vec_IntPush( &p->vTemp, InItem );
    // check unary operator
    if ( Psr_ManIsChar(p, ';') )
    {
        Vec_IntPush( &p->vTemp, 0 );
        Vec_IntPush( &p->vTemp, OutItem );
        Oper = fCompl ? BAC_BOX_INV : BAC_BOX_BUF;
        Psr_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp );
        return 1;
    }
    if ( Psr_ManIsChar(p, '&') ) 
        Oper = BAC_BOX_AND;
    else if ( Psr_ManIsChar(p, '|') ) 
        Oper = BAC_BOX_OR;
    else if ( Psr_ManIsChar(p, '^') ) 
        Oper = BAC_BOX_XOR;
    else if ( Psr_ManIsChar(p, '?') ) 
        Oper = BAC_BOX_MUX;
    else                                    return Psr_ManErrorSet(p, "Unrecognized operator in the assign-statement.", 0);
    p->pCur++; 
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 24.", 0);
    if ( Psr_ManIsChar(p, '~') ) 
    { 
        fCompl2 = 1; 
        p->pCur++; 
    }
    // read second name
    InItem = Psr_ManReadSignal( p );
    if ( InItem == 0 )                      return Psr_ManErrorSet(p, "Cannot read second input name in the assign-statement.", 0);
    Vec_IntPush( &p->vTemp, 0 );
    Vec_IntPush( &p->vTemp, InItem );
    // read third argument
    if ( Oper == BAC_BOX_MUX )
    {
        assert( fCompl == 0 ); 
        if ( !Psr_ManIsChar(p, ':') )       return Psr_ManErrorSet(p, "Expected colon in the MUX assignment.", 0);
        p->pCur++; 
        // read third name
        InItem = Psr_ManReadSignal( p );
        if ( InItem == 0 )                  return Psr_ManErrorSet(p, "Cannot read third input name in the assign-statement.", 0);
        Vec_IntPush( &p->vTemp, 0 );
        Vec_IntPush( &p->vTemp, InItem );
        if ( !Psr_ManIsChar(p, ';') )       return Psr_ManErrorSet(p, "Expected semicolon at the end of the assign-statement.", 0);
    }
    else
    {
        // figure out operator
        if ( Oper == BAC_BOX_AND )
        {
            if ( fCompl && !fCompl2 )
                Oper = BAC_BOX_SHARPL;
            else if ( !fCompl && fCompl2 )
                Oper = BAC_BOX_SHARP;
            else if ( fCompl && fCompl2 )
                Oper = BAC_BOX_NOR;
        }
        else if ( Oper == BAC_BOX_OR )
        {
            if ( fCompl && fCompl2 )
                Oper = BAC_BOX_NAND;
            else assert( !fCompl && !fCompl2 );
        }
        else if ( Oper == BAC_BOX_XOR )
        {
            if ( fCompl && !fCompl2 )
                Oper = BAC_BOX_XNOR;
            else assert( !fCompl && !fCompl2 );
        }
    }
    // write binary operator
    Vec_IntPush( &p->vTemp, 0 );
    Vec_IntPush( &p->vTemp, OutItem );
    Psr_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp );
    return 1;
}
static inline int Psr_ManReadInstance( Psr_Man_t * p, int Func )
{
    int InstId, Status;
/*
    static Counter = 0;
    if ( ++Counter == 7 )
    {
        int s=0;
    }
*/
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 25.", 0);
    if ( (InstId = Psr_ManReadName(p)) )
        if (Psr_ManUtilSkipSpaces(p))       return Psr_ManErrorSet(p, "Error number 26.", 0);
    if ( !Psr_ManIsChar(p, '(') )           return Psr_ManErrorSet(p, "Expecting \"(\" in module instantiation.", 0);
    p->pCur++;
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 27.", 0);
    if ( Psr_ManIsChar(p, '.') ) // box
        Status = Psr_ManReadSignalList2(p, &p->vTemp);
    else  // node
    {
        //char * s = Abc_NamStr(p->pStrs, Func);
        // translate elementary gate
        int iFuncNew = Psr_ManIsVerilogModule(p, Abc_NamStr(p->pStrs, Func));
        if ( iFuncNew == 0 )                return Psr_ManErrorSet(p, "Cannot find elementary gate.", 0);
        Func = iFuncNew;
        Status = Psr_ManReadSignalList( p, &p->vTemp, ')', 1 );
    }
    if ( Status == 0 )                      return Psr_ManErrorSet(p, "Error number 28.", 0);
    assert( Psr_ManIsChar(p, ')') );
    p->pCur++;
    if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 29.", 0);
    if ( !Psr_ManIsChar(p, ';') )           return Psr_ManErrorSet(p, "Expecting semicolon in the instance.", 0);
    // add box 
    Psr_NtkAddBox( p->pNtk, Func, InstId, &p->vTemp );
    return 1;
}
static inline int Psr_ManReadArguments( Psr_Man_t * p )
{
    int iRange = 0, iType = -1;
    Vec_Int_t * vSigs[3]  = { &p->pNtk->vInputs,  &p->pNtk->vOutputs,  &p->pNtk->vInouts  };
    Vec_Int_t * vSigsR[3] = { &p->pNtk->vInputsR, &p->pNtk->vOutputsR, &p->pNtk->vInoutsR };
    assert( Psr_ManIsChar(p, '(') );
    p->pCur++;
    if ( Psr_ManUtilSkipSpaces(p) )             return Psr_ManErrorSet(p, "Error number 30.", 0);
    while ( 1 )
    {
        int iName = Psr_ManReadName( p );
        if ( iName == 0 )                       return Psr_ManErrorSet(p, "Error number 31.", 0);
        if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 32.", 0);
        if ( iName >= PRS_VER_INPUT && iName <= PRS_VER_INOUT ) // declaration
        {
            iType = iName;
            if ( Psr_ManIsChar(p, '[') )
            {
                iRange = Psr_ManReadRange(p);
                if ( iRange == 0 )              return Psr_ManErrorSet(p, "Error number 33.", 0);
                if ( Psr_ManUtilSkipSpaces(p) ) return Psr_ManErrorSet(p, "Error number 34.", 0);
            }
            iName = Psr_ManReadName( p );
            if ( iName == 0 )                   return Psr_ManErrorSet(p, "Error number 35.", 0);
        }
        if ( iType > 0 )
        {
            Vec_IntPush( vSigs[iType - PRS_VER_INPUT], iName );
            Vec_IntPush( vSigsR[iType - PRS_VER_INPUT], iRange );
            Vec_IntPush( &p->pNtk->vOrder, Abc_Var2Lit2(iName, iType) );
        }
        if ( Psr_ManIsChar(p, ')') )
            break;
        if ( !Psr_ManIsChar(p, ',') )           return Psr_ManErrorSet(p, "Expecting comma in the instance.", 0);
        p->pCur++;
        if ( Psr_ManUtilSkipSpaces(p) )         return Psr_ManErrorSet(p, "Error number 36.", 0);
    }
    // check final
    assert( Psr_ManIsChar(p, ')') );
    return 1;
}
// this procedure can return:
// 0 = reached end-of-file; 1 = successfully parsed; 2 = recognized as primitive; 3 = failed and skipped; 4 = error (failed and could not skip)
static inline int Psr_ManReadModule( Psr_Man_t * p )
{
    int iToken, Status;
    if ( p->pNtk != NULL )                  return Psr_ManErrorSet(p, "Parsing previous module is unfinished.", 4);
    if ( Psr_ManUtilSkipSpaces(p) )
    { 
        Psr_ManErrorClear( p );       
        return 0; 
    }
    // read keyword
    iToken = Psr_ManReadName( p );
    if ( iToken != PRS_VER_MODULE )         return Psr_ManErrorSet(p, "Cannot read \"module\" keyword.", 4);
    if ( Psr_ManUtilSkipSpaces(p) )         return 4;
    // read module name
    iToken = Psr_ManReadName( p );
    if ( iToken == 0 )                      return Psr_ManErrorSet(p, "Cannot read module name.", 4);
    if ( Psr_ManIsKnownModule(p, Abc_NamStr(p->pStrs, iToken)) )
    {
        if ( Psr_ManUtilSkipUntilWord( p, "endmodule" ) ) return Psr_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4);
        //printf( "Warning! Skipped known module \"%s\".\n", Abc_NamStr(p->pStrs, iToken) );
        Vec_IntPush( &p->vKnown, iToken );
        return 2;
    }
    Psr_ManInitializeNtk( p, iToken, 1 );
    // skip arguments
    if ( Psr_ManUtilSkipSpaces(p) )         return 4;
    if ( !Psr_ManIsChar(p, '(') )           return Psr_ManErrorSet(p, "Cannot find \"(\" in the argument declaration.", 4);
    if ( !Psr_ManReadArguments(p) )         return 4;
    assert( *p->pCur == ')' );
    p->pCur++;
    if ( Psr_ManUtilSkipSpaces(p) )         return 4;
    // read declarations and instances
    while ( Psr_ManIsChar(p, ';') )
    {
        p->pCur++;
        if ( Psr_ManUtilSkipSpaces(p) )     return 4;
        iToken = Psr_ManReadName( p );
        if ( iToken == PRS_VER_ENDMODULE )
        {
            Vec_IntPush( &p->vSucceeded, p->pNtk->iModuleName );
            Psr_ManFinalizeNtk( p );
            return 1;
        }
        if ( iToken >= PRS_VER_INPUT && iToken <= PRS_VER_WIRE ) // declaration
            Status = Psr_ManReadDeclaration( p, iToken );
        else if ( iToken == PRS_VER_REG || iToken == PRS_VER_DEFPARAM ) // unsupported keywords
            Status = Psr_ManUtilSkipUntil( p, ';' );
        else // read instance
        {
            if ( iToken == PRS_VER_ASSIGN )
                Status = Psr_ManReadAssign( p );
            else
                Status = Psr_ManReadInstance( p, iToken );
            if ( Status == 0 )
            {
                if ( Psr_ManUtilSkipUntilWord( p, "endmodule" ) ) return Psr_ManErrorSet(p, "Cannot find \"endmodule\" keyword.", 4);
                //printf( "Warning! Failed to parse \"%s\". Adding module \"%s\" as blackbox.\n", 
                //    Abc_NamStr(p->pStrs, iToken), Abc_NamStr(p->pStrs, p->pNtk->iModuleName) );
                Vec_IntPush( &p->vFailed, p->pNtk->iModuleName );
                // cleanup
                Vec_IntErase( &p->pNtk->vWires );
                Vec_IntErase( &p->pNtk->vWiresR );
                Vec_IntErase( &p->pNtk->vSlices );
                Vec_IntErase( &p->pNtk->vConcats );
                Vec_IntErase( &p->pNtk->vBoxes );
                Vec_IntErase( &p->pNtk->vObjs );
                p->fUsingTemp2 = 0;
                // add
                Psr_ManFinalizeNtk( p );
                Psr_ManErrorClear( p );
                return 3;
            }
        }
        if ( !Status )                      return 4;
        if ( Psr_ManUtilSkipSpaces(p) )     return 4;
    }
    return Psr_ManErrorSet(p, "Cannot find \";\" in the module definition.", 4);
}
static inline int Psr_ManReadDesign( Psr_Man_t * p )
{
    while ( 1 )
    {
        int RetValue = Psr_ManReadModule( p );
        if ( RetValue == 0 ) // end of file
            break;
        if ( RetValue == 1 ) // successfully parsed
            continue;
        if ( RetValue == 2 ) // recognized as primitive
            continue;
        if ( RetValue == 3 ) // failed and skipped
            continue;
        if ( RetValue == 4 ) // error
            return 0;
        assert( 0 );
    }
    return 1;
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Psr_ManPrintModules( Psr_Man_t * p )
{
    char * pName; int i; 
    printf( "Succeeded parsing %d models:\n", Vec_IntSize(&p->vSucceeded) );
    Psr_ManForEachNameVec( &p->vSucceeded, p, pName, i )
        printf( " %s", pName );
    printf( "\n" );
    printf( "Skipped %d known models:\n", Vec_IntSize(&p->vKnown) );
    Psr_ManForEachNameVec( &p->vKnown, p, pName, i )
        printf( " %s", pName );
    printf( "\n" );
    printf( "Skipped %d failed models:\n", Vec_IntSize(&p->vFailed) );
    Psr_ManForEachNameVec( &p->vFailed, p, pName, i )
        printf( " %s", pName );
    printf( "\n" );
}

/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Ptr_t * Psr_ManReadVerilog( char * pFileName )
{
    Vec_Ptr_t * vPrs = NULL;
    Psr_Man_t * p = Psr_ManAlloc( pFileName );
    if ( p == NULL )
        return NULL;
    Psr_NtkAddVerilogDirectives( p );
    Psr_ManReadDesign( p );   
    //Psr_ManPrintModules( p );
    if ( Psr_ManErrorPrint(p) )
        ABC_SWAP( Vec_Ptr_t *, vPrs, p->vNtks );
    Psr_ManFree( p );
    return vPrs;
}

void Psr_ManReadVerilogTest( char * pFileName )
{
    abctime clk = Abc_Clock();
    extern void Psr_ManWriteVerilog( char * pFileName, Vec_Ptr_t * p );
    Vec_Ptr_t * vPrs = Psr_ManReadVerilog( "c/hie/dump/1/netlist_1.v" );
//    Vec_Ptr_t * vPrs = Psr_ManReadVerilog( "aga/me/me_wide.v" );
//    Vec_Ptr_t * vPrs = Psr_ManReadVerilog( "aga/ray/ray_wide.v" );
    if ( !vPrs ) return;
    printf( "Finished reading %d networks. ", Vec_PtrSize(vPrs) );
    printf( "NameIDs = %d. ", Abc_NamObjNumMax(Psr_ManNameMan(vPrs)) );
    printf( "Memory = %.2f MB. ", 1.0*Psr_ManMemory(vPrs)/(1<<20) );
    Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
    Psr_ManWriteVerilog( "c/hie/dump/1/netlist_1_out_new.v", vPrs );
//    Psr_ManWriteVerilog( "aga/me/me_wide_out.v", vPrs );
//    Psr_ManWriteVerilog( "aga/ray/ray_wide_out.v", vPrs );
//    Abc_NamPrint( p->pStrs );
    Psr_ManVecFree( vPrs );
}


////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END