diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/aig/gia/giaDup.c | 14 | ||||
| -rw-r--r-- | src/aig/gia/giaPat2.c | 4 | ||||
| -rw-r--r-- | src/aig/miniaig/abcOper.h | 4 | ||||
| -rw-r--r-- | src/base/main/mainInt.h | 1 | ||||
| -rw-r--r-- | src/base/wlc/wlcCom.c | 336 | ||||
| -rw-r--r-- | src/base/wln/module.make | 2 | ||||
| -rw-r--r-- | src/base/wln/wln.h | 4 | ||||
| -rw-r--r-- | src/base/wln/wlnBlast.c | 388 | ||||
| -rw-r--r-- | src/base/wln/wlnRead.c | 1733 | ||||
| -rw-r--r-- | src/base/wln/wlnRtl.c | 48 | 
10 files changed, 2379 insertions, 155 deletions
| diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index da4881cd..55f8901f 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1086,6 +1086,20 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo )      Gia_ManSetRegNum( pNew, Gia_ManRegNum(pOne) + Gia_ManRegNum(pTwo) );      return pNew;  } +void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ) +{ +    Gia_Obj_t * pObj; int i; +    assert( Vec_IntSize(vLits) == Gia_ManCiNum(p) ); +    Gia_ManConst0(p)->Value = 0; +    Gia_ManForEachCi( p, pObj, i ) +        pObj->Value = Vec_IntEntry(vLits, i); +    Gia_ManForEachAnd( p, pObj, i ) +        pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +    Vec_IntClear( vLits ); +    Gia_ManForEachCo( p, pObj, i ) +        Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) ); +    assert( Vec_IntSize(vLits) == Gia_ManCoNum(p) ); +}  /**Function************************************************************* diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index f2cdfe79..fef4cf5a 100644 --- a/src/aig/gia/giaPat2.c +++ b/src/aig/gia/giaPat2.c @@ -1025,9 +1025,9 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie      if ( fVerbose )          printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts );      if ( fVerbose ) -        Abc_PrintTime( 1, "Simulation time ", clkSim ); +        Abc_PrintTime( 1, "Simulation time  ", clkSim );      if ( fVerbose ) -        Abc_PrintTime( 1, "SAT solving time", clkSat ); +        Abc_PrintTime( 1, "SAT solving time ", clkSat );      //Vec_WecPrint( vCexes, 0 );      if ( vOuts != vOuts0 )          Vec_IntFreeP( &vOuts ); diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h index c3d6e176..cbe2a0f3 100644 --- a/src/aig/miniaig/abcOper.h +++ b/src/aig/miniaig/abcOper.h @@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type )      if ( Type == ABC_OPER_ZEROPAD      )   return "zPad";         if ( Type == ABC_OPER_SIGNEXT      )   return "sExt";    +    if ( Type == ABC_OPER_BIT_MUX      )   return "mux";        +    if ( Type == ABC_OPER_SEL_NMUX     )   return "nmux";    +    if ( Type == ABC_OPER_SEL_SEL      )   return "pmux";    +      if ( Type == ABC_OPER_CONST        )   return "const";        if ( Type == ABC_OPER_TABLE        )   return "table";        if ( Type == ABC_OPER_LUT          )   return "lut";   diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index e860878e..5325adfe 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -145,6 +145,7 @@ struct Abc_Frame_t_      void *          pAbc85Delay;      void *          pAbcWlc;      Vec_Int_t *     pAbcWlcInv; +    void *          pAbcRtl;      void *          pAbcBac;      void *          pAbcCba;      void *          pAbcPla; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index b1573e73..d8b8247a 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,7 +32,6 @@ ABC_NAMESPACE_IMPL_START  static int  Abc_CommandReadWlc    ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int  Abc_CommandWriteWlc   ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int  Abc_CommandYosys      ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int  Abc_CommandPs         ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int  Abc_CommandCone       ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int  Abc_CommandAbs        ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -55,12 +54,20 @@ static int  Abc_CommandInvPut     ( Abc_Frame_t * pAbc, int argc, char ** argv )  static int  Abc_CommandInvMin     ( Abc_Frame_t * pAbc, int argc, char ** argv );  static int  Abc_CommandTest       ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int  Abc_CommandYosys      ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int  Abc_CommandSolve      ( Abc_Frame_t * pAbc, int argc, char ** argv ); +  static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc )                       { return (Wlc_Ntk_t *)pAbc->pAbcWlc;                      }  static inline void        Wlc_AbcFreeNtk( Abc_Frame_t * pAbc )                      { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc));  }  static inline void        Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk )  { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk;             }  static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc )                       { return pAbc->pAbcWlcInv;                                } + +static inline Rtl_Lib_t * Wlc_AbcGetRtl( Abc_Frame_t * pAbc )                       { return (Rtl_Lib_t *)pAbc->pAbcRtl;                      } +static inline void        Wlc_AbcFreeRtl( Abc_Frame_t * pAbc )                      { if ( pAbc->pAbcRtl ) Rtl_LibFree(Wlc_AbcGetRtl(pAbc));  } +static inline void        Wlc_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib )  { Wlc_AbcFreeRtl(pAbc); pAbc->pAbcRtl = pLib;             } +  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         ///  //////////////////////////////////////////////////////////////////////// @@ -80,7 +87,6 @@ void Wlc_Init( Abc_Frame_t * pAbc )  {      Cmd_CommandAdd( pAbc, "Word level", "%read",        Abc_CommandReadWlc,    0 );      Cmd_CommandAdd( pAbc, "Word level", "%write",       Abc_CommandWriteWlc,   0 ); -    Cmd_CommandAdd( pAbc, "Word level", "%yosys",       Abc_CommandYosys,      0 );      Cmd_CommandAdd( pAbc, "Word level", "%ps",          Abc_CommandPs,         0 );      Cmd_CommandAdd( pAbc, "Word level", "%cone",        Abc_CommandCone,       0 );      Cmd_CommandAdd( pAbc, "Word level", "%abs",         Abc_CommandAbs,        0 ); @@ -97,6 +103,9 @@ void Wlc_Init( Abc_Frame_t * pAbc )      Cmd_CommandAdd( pAbc, "Word level", "%show",        Abc_CommandShow,       0 );      Cmd_CommandAdd( pAbc, "Word level", "%test",        Abc_CommandTest,       0 ); +    Cmd_CommandAdd( pAbc, "Word level", "%yosys",       Abc_CommandYosys,      0 ); +    Cmd_CommandAdd( pAbc, "Word level", "%solve",       Abc_CommandSolve,      0 ); +      Cmd_CommandAdd( pAbc, "Word level", "inv_ps",       Abc_CommandInvPs,      0 );      Cmd_CommandAdd( pAbc, "Word level", "inv_print",    Abc_CommandInvPrint,   0 );      Cmd_CommandAdd( pAbc, "Word level", "inv_check",    Abc_CommandInvCheck,   0 ); @@ -308,130 +317,6 @@ usage:    SeeAlso     []  ******************************************************************************/ -int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ -    extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); -    extern Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ); - -    FILE * pFile; -    char * pFileName = NULL; -    char * pTopModule= NULL; -    int fCollapse    =    0; -    int fBlast       =    0; -    int fInvert      =    0; -    int fTechMap     =    0; -    int fSkipStrash  =    0; -    int c, fVerbose  =    0; -    Extra_UtilGetoptReset(); -    while ( ( c = Extra_UtilGetopt( argc, argv, "Tcaismvh" ) ) != EOF ) -    { -        switch ( c ) -        { -        case 'T': -            if ( globalUtilOptind >= argc ) -            { -                Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); -                goto usage; -            } -            pTopModule = argv[globalUtilOptind]; -            globalUtilOptind++; -            break; -        case 'c': -            fCollapse ^= 1; -            break; -        case 'a': -            fBlast ^= 1; -            break; -        case 'i': -            fInvert ^= 1; -            break; -        case 's': -            fSkipStrash ^= 1; -            break; -        case 'm': -            fTechMap ^= 1; -            break; -        case 'v': -            fVerbose ^= 1; -            break; -        case 'h': -            goto usage; -        default: -            goto usage; -        } -    } -    if ( argc != globalUtilOptind + 1 ) -    { -        printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); -        return 0; -    } -    // get the file name -    pFileName = argv[globalUtilOptind]; -    if ( (pFile = fopen( pFileName, "r" )) == NULL ) -    { -        Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); -        if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) -            Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); -        Abc_Print( 1, "\n" ); -        return 0; -    } -    fclose( pFile ); - -    // perform reading -    if ( fBlast ) -    { -        Gia_Man_t * pNew = NULL; -        if ( !strcmp( Extra_FileNameExtension(pFileName), "v" )  ) -            pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); -        else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" )  ) -            pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); -        else -        { -            printf( "Abc_CommandYosys(): Unknown file extension.\n" ); -            return 0; -        } -        Abc_FrameUpdateGia( pAbc, pNew ); -    } -    else -    { -        Wln_Ntk_t * pNtk = NULL; -        if ( !strcmp( Extra_FileNameExtension(pFileName), "v" )  ) -            pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose ); -        else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" )  ) -            pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose ); -        else -        { -            printf( "Abc_CommandYosys(): Unknown file extension.\n" ); -            return 0; -        } -        //Wlc_AbcUpdateNtk( pAbc, pNtk ); -    } -    return 0; -usage: -    Abc_Print( -2, "usage: %%yosys [-T <module>] [-caismvh] <file_name>\n" ); -    Abc_Print( -2, "\t         reads Verilog or SystemVerilog using Yosys\n" ); -    Abc_Print( -2, "\t-T     : specify the top module name (default uses \"-auto-top\"\n" ); -    Abc_Print( -2, "\t-c     : toggle collapsing the design using Yosys [default = %s]\n", fCollapse? "yes": "no" ); -    Abc_Print( -2, "\t-a     : toggle bit-blasting the design using Yosys [default = %s]\n", fBlast? "yes": "no" ); -    Abc_Print( -2, "\t-i     : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); -    Abc_Print( -2, "\t-s     : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); -    Abc_Print( -2, "\t-m     : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); -    Abc_Print( -2, "\t-v     : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); -    Abc_Print( -2, "\t-h     : print the command usage\n"); -    return 1; -} - -/**Function******************************************************************** - -  Synopsis    [] - -  Description [] - -  SideEffects [] - -  SeeAlso     [] - -******************************************************************************/  int Abc_CommandPs( Abc_Frame_t * pAbc, int argc, char ** argv )  {      Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); @@ -2097,6 +1982,205 @@ usage:      return 1;  } + +/**Function******************************************************************** + +  Synopsis    [] + +  Description [] + +  SideEffects [] + +  SeeAlso     [] + +******************************************************************************/ +int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); +    extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose ); + +    FILE * pFile; +    char * pFileName = NULL; +    char * pTopModule= NULL; +    int fBlast       =    0; +    int fInvert      =    0; +    int fTechMap     =    1; +    int fSkipStrash  =    0; +    int fCollapse    =    0; +    int c, fVerbose  =    0; +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "Tbismcvh" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'T': +            if ( globalUtilOptind >= argc ) +            { +                Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); +                goto usage; +            } +            pTopModule = argv[globalUtilOptind]; +            globalUtilOptind++; +            break; +        case 'b': +            fBlast ^= 1; +            break; +        case 'i': +            fInvert ^= 1; +            break; +        case 's': +            fSkipStrash ^= 1; +            break; +        case 'm': +            fTechMap ^= 1; +            break; +        case 'c': +            fCollapse ^= 1; +            break; +        case 'v': +            fVerbose ^= 1; +            break; +        case 'h': +            goto usage; +        default: +            goto usage; +        } +    } +    if ( argc != globalUtilOptind + 1 ) +    { +        printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); +        return 0; +    } +    // get the file name +    pFileName = argv[globalUtilOptind]; +    if ( (pFile = fopen( pFileName, "r" )) == NULL ) +    { +        Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); +        if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) +            Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); +        Abc_Print( 1, "\n" ); +        return 0; +    } +    fclose( pFile ); + +    // perform reading +    if ( fBlast ) +    { +        Gia_Man_t * pNew = NULL; +        if ( !strcmp( Extra_FileNameExtension(pFileName), "v" )  ) +            pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); +        else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" )  ) +            pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); +        else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" )  ) +            pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); +        else +        { +            printf( "Abc_CommandYosys(): Unknown file extension.\n" ); +            return 0; +        } +        Abc_FrameUpdateGia( pAbc, pNew ); +    } +    else +    { +        Rtl_Lib_t * pLib = NULL; +        if ( !strcmp( Extra_FileNameExtension(pFileName), "v" )  ) +            pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); +        else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" )  ) +            pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); +        else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" )  ) +            pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); +        else +        { +            printf( "Abc_CommandYosys(): Unknown file extension.\n" ); +            return 0; +        } +        Wlc_AbcUpdateRtl( pAbc, pLib ); +    } +    return 0; +usage: +    Abc_Print( -2, "usage: %%yosys [-T <module>] [-bismcvh] <file_name>\n" ); +    Abc_Print( -2, "\t         reads Verilog or SystemVerilog using Yosys\n" ); +    Abc_Print( -2, "\t-T     : specify the top module name (default uses \"-auto-top\"\n" ); +    Abc_Print( -2, "\t-b     : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" ); +    Abc_Print( -2, "\t-i     : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); +    Abc_Print( -2, "\t-s     : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); +    Abc_Print( -2, "\t-m     : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); +    Abc_Print( -2, "\t-c     : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "yes": "no" ); +    Abc_Print( -2, "\t-v     : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); +    Abc_Print( -2, "\t-h     : print the command usage\n"); +    return 1; +} + +/**Function******************************************************************** + +  Synopsis    [] + +  Description [] + +  SideEffects [] + +  SeeAlso     [] + +******************************************************************************/ +int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ +    extern void Rtl_LibPrintStats( Rtl_Lib_t * p ); +    extern void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p ); +    extern void Rtl_LibNormRanges( Rtl_Lib_t * pLib ); +    extern void Rtl_LibOrderWires( Rtl_Lib_t * pLib ); +    extern void Rtl_LibOrderCells( Rtl_Lib_t * pLib ); +    extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); +    extern void Rtl_LibReorderModules( Rtl_Lib_t * pLib ); +    extern void Rtl_LibSolve( Rtl_Lib_t * pLib ); +    extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); + +    Gia_Man_t * pGia = NULL; +    Rtl_Lib_t * pLib = Wlc_AbcGetRtl(pAbc); +    int c, fPrepro = 0, fVerbose  = 0; +    Extra_UtilGetoptReset(); +    while ( ( c = Extra_UtilGetopt( argc, argv, "pvh" ) ) != EOF ) +    { +        switch ( c ) +        { +        case 'p': +            fPrepro ^= 1; +            break; +        case 'v': +            fVerbose ^= 1; +            break; +        case 'h': +            goto usage; +        default: +            goto usage; +        } +    } +    Rtl_LibPrintStats( pLib ); +    //Rtl_LibPrint( NULL, pLib ); +    Rtl_LibOrderWires( pLib ); +    Rtl_LibOrderCells( pLib ); + +    Rtl_LibBlast( pLib ); +    //Rtl_LibReorderModules( pLib ); +    //Rtl_LibPrintStats( pLib ); + +    if ( fPrepro ) +        Rtl_LibPreprocess( pLib ); +    Rtl_LibSolve( pLib ); + +    //Rtl_LibPrint( NULL, pLib ); +    Wlc_AbcUpdateRtl( pAbc, NULL ); +    Gia_ManStopP( &pGia ); +    return 0; +usage: +    Abc_Print( -2, "usage: %%solve [-pvh]\n" ); +    Abc_Print( -2, "\t         experiments with word-level networks\n" ); +    Abc_Print( -2, "\t-p     : toggle preprocessing for verification [default = %s]\n", fPrepro? "yes": "no" ); +    Abc_Print( -2, "\t-v     : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); +    Abc_Print( -2, "\t-h     : print the command usage\n"); +    return 1; +} + +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wln/module.make b/src/base/wln/module.make index 308f7689..7277f30b 100644 --- a/src/base/wln/module.make +++ b/src/base/wln/module.make @@ -1,8 +1,10 @@  SRC +=    src/base/wln/wln.c \ +    src/base/wln/wlnBlast.c \      src/base/wln/wlnMem.c \      src/base/wln/wlnNdr.c \      src/base/wln/wlnNtk.c \      src/base/wln/wlnObj.c \ +    src/base/wln/wlnRead.c \      src/base/wln/wlnRetime.c \      src/base/wln/wlnRtl.c \      src/base/wln/wlnWlc.c \ diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h index 93a1a92a..c658a2fe 100644 --- a/src/base/wln/wln.h +++ b/src/base/wln/wln.h @@ -251,6 +251,10 @@ extern void           Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk );  /*=== wlcWriteVer.c ========================================================*/  extern void           Wln_WriteVer( Wln_Ntk_t * p, char * pFileName ); +/*=== wlcRead.c ========================================================*/ +typedef struct Rtl_Lib_t_ Rtl_Lib_t; +extern Rtl_Lib_t *    Rtl_LibReadFile( char * pFileName, char * pFileSpec ); +extern void           Rtl_LibFree( Rtl_Lib_t * p );  ABC_NAMESPACE_HEADER_END diff --git a/src/base/wln/wlnBlast.c b/src/base/wln/wlnBlast.c new file mode 100644 index 00000000..a3ac73c0 --- /dev/null +++ b/src/base/wln/wlnBlast.c @@ -0,0 +1,388 @@ +/**CFile**************************************************************** + +  FileName    [wlnBlast.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Word-level network.] + +  Synopsis    [] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 23, 2018.] + +  Revision    [$Id: wlnBlast.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "base/wlc/wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rtl_VecExtend( Vec_Int_t * p, int nRange, int fSigned ) +{ +    Vec_IntFillExtra( p, nRange, fSigned ? Vec_IntEntryLast(p) : 0 ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 ) +{ +    extern void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes ); +    extern int  Wlc_BlastReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type ); +    extern int  Wlc_BlastLess( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits ); +    extern int  Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits ); +    extern void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes ); +    extern void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes ); +    extern int  Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0 +    extern void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0 +    extern int  Wlc_NtkCountConstBits( int * pArray, int nSize ); +    extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ); +    extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ); +    extern void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes ); +    extern void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes ); +    extern void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes ); +    extern void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes ); + +    int k, iLit, iLit0, iLit1; +    if ( nIns == 1 ) +    { +        Vec_Int_t * vArg = vDatas; +        Vec_Int_t * vRes = vDatas+3; +        assert( Vec_IntSize(vRes) == 0 ); +        if ( Type == ABC_OPER_BIT_INV )   // Y = ~A    $not   +        { +            assert( Vec_IntSize(vArg) == nRange ); +            Vec_IntForEachEntry( vArg, iLit, k ) +                Vec_IntPush( vRes, Abc_LitNot(iLit) ); +            return; +        } +        if ( Type == ABC_OPER_BIT_BUF )   // Y = +A    $pos  +        { +            assert( Vec_IntSize(vArg) == nRange ); +            Vec_IntForEachEntry( vArg, iLit, k ) +                Vec_IntPush( vRes, iLit ); +            return; +        } +        if ( Type == ABC_OPER_ARI_MIN )   // Y = -A    $neg  +        { +            assert( Vec_IntSize(vArg) == nRange ); +            Wlc_BlastMinus( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), vRes ); +            return; +        } +        if ( Type == ABC_OPER_RED_AND )   // Y = &A    $reduce_and +        { +            assert( nRange == 1 ); +            Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_AND ) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        if ( Type == ABC_OPER_RED_OR )    // Y = |A    $reduce_or     $reduce_bool  +        { +            assert( nRange == 1 ); +            Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        if ( Type == ABC_OPER_RED_XOR )   // Y = ^A    $reduce_xor   +        { +            assert( nRange == 1 ); +            Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_XOR ) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        if ( Type == ABC_OPER_RED_NXOR )  // Y = ~^A   $reduce_xnor  +        { +            assert( nRange == 1 ); +            Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_NXOR ) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        if ( Type == ABC_OPER_LOGIC_NOT ) // Y = !A    $logic_not    +        { +            int iLit = Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ); +            assert( nRange == 1 ); +            Vec_IntFill( vRes, 1, Abc_LitNot(iLit) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        assert( 0 ); +        return; +    } + +    if ( nIns == 2 ) +    { +        Vec_Int_t * vArg0 = vDatas; +        Vec_Int_t * vArg1 = vDatas+1; +        Vec_Int_t * vRes  = vDatas+3; +        int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(Vec_IntSize(vArg0), Vec_IntSize(vArg1)) ); +        int nSizeArg0 = Vec_IntSize(vArg0); +        int nSizeArg1 = Vec_IntSize(vArg1); +        Rtl_VecExtend( vArg0, nRangeMax, fSign0 ); +        Rtl_VecExtend( vArg1, nRangeMax, fSign1 ); +        assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) ); +        assert( Vec_IntSize(vRes) == 0 ); +        if ( Type == ABC_OPER_LOGIC_AND )     // Y = A && B   $logic_and   +        { +            int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR ); +            int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR ); +            assert( 1 == nRange ); +            Vec_IntFill( vRes, 1, Gia_ManHashAnd(pNew, iLit0, iLit1) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        if ( Type == ABC_OPER_LOGIC_OR )      // Y = A || B   $logic_or     +        { +            int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR ); +            int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR ); +            assert( 1 == nRange ); +            Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, iLit0, iLit1) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } + +        if ( Type == ABC_OPER_BIT_AND )     // Y = A & B    $and +        { +            Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) +                Vec_IntPush( vRes, Gia_ManHashAnd(pNew, iLit0, iLit1) ); +            Vec_IntShrink( vRes, nRange ); +            return; +        } +        if ( Type == ABC_OPER_BIT_OR )      // Y = A | B    $or     +        { +            Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) +                Vec_IntPush( vRes, Gia_ManHashOr(pNew, iLit0, iLit1) ); +            Vec_IntShrink( vRes, nRange ); +            return; +        } +        if ( Type == ABC_OPER_BIT_XOR )     // Y = A ^ B    $xor +        {  +            Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) +                Vec_IntPush( vRes, Gia_ManHashXor(pNew, iLit0, iLit1) ); +            Vec_IntShrink( vRes, nRange ); +            return; +        } +        if ( Type == ABC_OPER_BIT_NXOR )    // Y = A ~^ B   $xnor +        { +            assert( Vec_IntSize(vArg0) == nRange ); +            Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) +                Vec_IntPush( vRes, Abc_LitNot(Gia_ManHashXor(pNew, iLit0, iLit1)) ); +            Vec_IntShrink( vRes, nRange ); +            return; +        } +/* +        if ( !strcmp(pType, "$lt") )          return ABC_OPER_COMP_LESS;     // Y = A <  B   $lt           +        if ( !strcmp(pType, "$le") )          return ABC_OPER_COMP_LESSEQU;  // Y = A <= B   $le          +        if ( !strcmp(pType, "$ge") )          return ABC_OPER_COMP_MOREEQU;  // Y = A >= B   $ge            +        if ( !strcmp(pType, "$gt") )          return ABC_OPER_COMP_MORE;     // Y = A >  B   $gt         +        if ( !strcmp(pType, "$eq") )          return ABC_OPER_COMP_EQU;      // Y = A == B   $eq          +        if ( !strcmp(pType, "$ne") )          return ABC_OPER_COMP_NOTEQU;   // Y = A != B   $ne          +*/ +        if ( Type == ABC_OPER_COMP_EQU || Type == ABC_OPER_COMP_NOTEQU ) +        { +            iLit = 0; +            assert( nRange == 1 ); +            Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) +                iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, iLit0, iLit1) );  +            Vec_IntFill( vRes, 1, Abc_LitNotCond(iLit, Type == ABC_OPER_COMP_EQU) ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +        if ( Type == ABC_OPER_COMP_LESS || Type == ABC_OPER_COMP_LESSEQU || +             Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_MOREEQU ) +        { +            int fSigned = fSign0 && fSign1; +            int fSwap   = (Type == ABC_OPER_COMP_MORE    || Type == ABC_OPER_COMP_LESSEQU); +            int fCompl  = (Type == ABC_OPER_COMP_MOREEQU || Type == ABC_OPER_COMP_LESSEQU); +            assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) ); +            assert( nRange == 1 ); +            if ( fSwap )  +                ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 ) +            if ( fSigned ) +                iLit = Wlc_BlastLessSigned( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) ); +            else +                iLit = Wlc_BlastLess( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) ); +            iLit = Abc_LitNotCond( iLit, fCompl ); +            Vec_IntFill( vRes, 1, iLit ); +            for ( k = 1; k < nRange; k++ ) +                Vec_IntPush( vRes, 0 ); +            return; +        } +/*         +        if ( !strcmp(pType, "$shl") )         return ABC_OPER_SHIFT_L;       // Y = A << B   $shl         +        if ( !strcmp(pType, "$shr") )         return ABC_OPER_SHIFT_R;       // Y = A >> B   $shr         +        if ( !strcmp(pType, "$sshl") )        return ABC_OPER_SHIFT_LA;      // Y = A <<< B  $sshl       +        if ( !strcmp(pType, "$sshr") )        return ABC_OPER_SHIFT_RA;      // Y = A >>> B  $sshr   +*/ +        if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA || +             Type == ABC_OPER_SHIFT_L || Type == ABC_OPER_SHIFT_LA ) +        { +            Vec_IntShrink( vArg1, nSizeArg1 ); +            if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA ) +                Wlc_BlastShiftRight( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, fSign0 && Type == ABC_OPER_SHIFT_RA, vRes ); +            else +                Wlc_BlastShiftLeft( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, 0, vRes ); +            Vec_IntShrink( vRes, nRange ); +            return; +        } +/* +        if ( !strcmp(pType, "$add") )         return ABC_OPER_ARI_ADD;       // Y = A + B    $add          +        if ( !strcmp(pType, "$sub") )         return ABC_OPER_ARI_SUB;       // Y = A - B    $sub          +        if ( !strcmp(pType, "$mul") )         return ABC_OPER_ARI_MUL;       // Y = A * B    $mul          +        if ( !strcmp(pType, "$div") )         return ABC_OPER_ARI_DIV;       // Y = A / B    $div          +        if ( !strcmp(pType, "$mod") )         return ABC_OPER_ARI_MOD;       // Y = A % B    $mod          +        if ( !strcmp(pType, "$pow") )         return ABC_OPER_ARI_POW;       // Y = A ** B   $pow         +*/ +        if ( Type == ABC_OPER_ARI_ADD || Type == ABC_OPER_ARI_SUB ) +        { +            //Vec_IntPrint( vArg0 ); +            //Vec_IntPrint( vArg1 ); +            Vec_IntAppend( vRes, vArg0 ); +            if ( Type == ABC_OPER_ARI_ADD ) +                Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 0 ); // result is in pFan0 (vRes) +            else  +                Wlc_BlastSubtract( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 1 ); // result is in pFan0 (vRes) +            Vec_IntShrink( vRes, nRange ); +            return; +        } +        if ( Type == ABC_OPER_ARI_MUL ) +        { +            int fBooth  = 1; +            int fCla    = 0; +            int fSigned = fSign0 && fSign1; +            Vec_IntShrink( vArg0, nSizeArg0 ); +            Vec_IntShrink( vArg1, nSizeArg1 ); +            if ( Wlc_NtkCountConstBits(Vec_IntArray(vArg0), Vec_IntSize(vArg0)) < Wlc_NtkCountConstBits(Vec_IntArray(vArg1), Vec_IntSize(vArg1)) ) +                ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 ) +            if ( fBooth ) +                Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL ); +            else +                Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL ); +            if ( nRange > Vec_IntSize(vRes) ) +                Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 ); +            else +                Vec_IntShrink( vRes, nRange ); +            assert( Vec_IntSize(vRes) == nRange ); +            return; +        } +        if ( Type == ABC_OPER_ARI_DIV || Type == ABC_OPER_ARI_MOD ) +        { +            int fDivBy0 = 1; // correct with 1 +            int fSigned = fSign0 && fSign1; +            if ( fSigned ) +                Wlc_BlastDividerSigned( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes ); +            else +                Wlc_BlastDivider( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes ); +            Vec_IntShrink( vRes, nRange ); +            if ( !fDivBy0 ) +                Wlc_BlastZeroCondition( pNew, Vec_IntArray(vArg1), nRange, vRes ); +            return; +        } +        if ( Type == ABC_OPER_ARI_POW ) +        { +            Vec_Int_t * vTemp = vDatas+4; +            Vec_IntGrow( vTemp, nRangeMax ); +            Vec_IntGrow( vRes,  nRangeMax ); +            Vec_IntShrink( vArg1, nSizeArg1 ); +            Wlc_BlastPower( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), Vec_IntSize(vArg1), vTemp, vRes ); +            Vec_IntShrink( vRes, nRange ); +            return; +        } +    } + +    if ( nIns == 3 ) +    { +        if ( Type == ABC_OPER_SEL_NMUX )    // $mux  +        { +            Vec_Int_t * vArg0 = vDatas; +            Vec_Int_t * vArg1 = vDatas+1; +            Vec_Int_t * vArgS = vDatas+2; +            Vec_Int_t * vRes  = vDatas+3; +            int iCtrl = Vec_IntEntry(vArgS, 0); +            //Vec_IntPrint( vArg0 ); +            //Vec_IntPrint( vArg1 ); +            //Vec_IntPrint( vArgS ); +            assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) ); +            assert( Vec_IntSize(vArg0) == nRange ); +            assert( Vec_IntSize(vArgS) == 1 ); +            assert( Vec_IntSize(vRes) == 0 ); +            Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) +                Vec_IntPush( vRes, Gia_ManHashMux(pNew, iCtrl, iLit1, iLit0) ); +            return; +        } +        if ( Type == ABC_OPER_SEL_SEL )    // $pmux  +        { +            int i, k, iLit; +            Vec_Int_t * vArgA = vDatas; +            Vec_Int_t * vArgB = vDatas+1; +            Vec_Int_t * vArgS = vDatas+2; +            Vec_Int_t * vRes  = vDatas+3; +            Vec_Int_t * vTemp = vDatas+4; +            assert( Vec_IntSize(vArgA) == nRange ); // widthA = widthY +            assert( Vec_IntSize(vArgB) == Vec_IntSize(vArgA)*Vec_IntSize(vArgS) ); // widthB == widthA*widthS +            assert( Vec_IntSize(vRes)  == 0 ); +            for ( i = 0; i < nRange; i++ ) +            { +                int iCond = 1; +                Vec_IntClear( vTemp ); +                Vec_IntForEachEntry( vArgS, iLit, k ) // iLit = S[i] +                { +                    //Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*(Vec_IntSize(vArgS)-1-k)+i)) ) ); // B[widthA*k+i] +                    Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*k+i)) ) ); // B[widthA*k+i] +                    iCond = Gia_ManHashAnd( pNew, iCond, Abc_LitNot(iLit) ); +                } +                Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iCond, Vec_IntEntry(vArgA, i)) ) ); +                Vec_IntPush( vRes, Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) ) ); +            } +            return; +        } +    } +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c new file mode 100644 index 00000000..492005fd --- /dev/null +++ b/src/base/wln/wlnRead.c @@ -0,0 +1,1733 @@ +/**CFile**************************************************************** + +  FileName    [wln.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Word-level network.] + +  Synopsis    [] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - September 23, 2018.] + +  Revision    [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "proof/cec/cec.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_LINE 10000 + +#define MAX_MAP     32 +#define CELL_NUM     8 +#define WIRE_NUM     5 +#define TEMP_NUM     5 + +//typedef struct Rtl_Lib_t_  Rtl_Lib_t; +struct Rtl_Lib_t_  +{ +    char *                pSpec;     // input file name +    Vec_Ptr_t *           vNtks;     // modules +    Abc_Nam_t *           pManName;  // object names +    Vec_Int_t             vConsts;   // constants +    Vec_Int_t             vSlices;   // selections +    Vec_Int_t             vConcats;  // concatenations +    FILE *                pFile;     // temp file +    Vec_Int_t *           vTokens;   // temp tokens +    int                   pMap[MAX_MAP];  // temp map +    Vec_Int_t *           vMap;      // mapping NameId into wires +    Vec_Int_t             vAttrTemp; // temp +    Vec_Int_t             vTemp[TEMP_NUM];  // temp +}; + +typedef struct Rtl_Ntk_t_  Rtl_Ntk_t; +struct Rtl_Ntk_t_  +{ +    int                   NameId;    // model name +    int                   nInputs;   // word-level inputs +    int                   nOutputs;  // word-level outputs +    Vec_Int_t             vWires;    // wires (name{upto,signed,in,out}+width+offset+number) +    Vec_Int_t             vCells;    // instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[6]mark+(attr+params+conns)) +    Vec_Int_t             vConns;    // connection pairs +    Vec_Int_t             vStore;    // storage for cells +    Vec_Int_t             vAttrs;    // attributes +    Rtl_Lib_t *           pLib;      // parent +    Vec_Int_t             vOrder;    // topological order +    Vec_Int_t             vLits;     // bit-level view +    Vec_Int_t             vBitTemp;  // storage for bits +    Gia_Man_t *           pGia;      // derived by bit-blasting +    int                   Slice0;    // first slice +    int                   Slice1;    // last slice +    int                   iCopy;     // place in array +}; + +static inline int         Rtl_LibNtkNum( Rtl_Lib_t * pLib )                { return Vec_PtrSize(pLib->vNtks);                  } +static inline Rtl_Ntk_t * Rtl_LibNtk( Rtl_Lib_t * pLib, int i )            { return (Rtl_Ntk_t *)Vec_PtrEntry(pLib->vNtks, i); } +static inline Rtl_Ntk_t * Rtl_LibTop( Rtl_Lib_t * pLib )                   { return Rtl_LibNtk( pLib, Rtl_LibNtkNum(pLib)-1 ); } + +static inline Rtl_Ntk_t * Rtl_NtkModule( Rtl_Ntk_t * p, int i )            { return Rtl_LibNtk( p->pLib, i );                  } + +static inline int         Rtl_NtkStrId( Rtl_Ntk_t * p, char * s )          { return Abc_NamStrFind(p->pLib->pManName, s);      } +static inline char *      Rtl_NtkStr( Rtl_Ntk_t * p, int h )               { return Abc_NamStr(p->pLib->pManName, h);          } +static inline char *      Rtl_NtkName( Rtl_Ntk_t * p )                     { return Rtl_NtkStr(p, p->NameId);                  } + +static inline FILE *      Rtl_NtkFile( Rtl_Ntk_t * p )                     { return p->pLib->pFile;                            } +static inline int         Rtl_NtkTokId( Rtl_Ntk_t * p, int i )             { return i < Vec_IntSize(p->pLib->vTokens) ? Vec_IntEntry(p->pLib->vTokens, i) : -1;                  } +static inline char *      Rtl_NtkTokStr( Rtl_Ntk_t * p, int i )            { return i < Vec_IntSize(p->pLib->vTokens) ? Rtl_NtkStr(p, Vec_IntEntry(p->pLib->vTokens, i)) : NULL; } +static inline int         Rtl_NtkTokCheck( Rtl_Ntk_t * p, int i, int Tok ) { return i == p->pLib->pMap[Tok];                                    } +static inline int         Rtl_NtkPosCheck( Rtl_Ntk_t * p, int i, int Tok ) { return Vec_IntEntry(p->pLib->vTokens, i) == p->pLib->pMap[Tok];    } + +static inline int         Rtl_NtkInputNum( Rtl_Ntk_t * p )                 { return p->nInputs;                                } +static inline int         Rtl_NtkOutputNum( Rtl_Ntk_t * p )                { return p->nOutputs;                               } +static inline int         Rtl_NtkAttrNum( Rtl_Ntk_t * p )                  { return Vec_IntSize(&p->vAttrs)/2;                 } +static inline int         Rtl_NtkWireNum( Rtl_Ntk_t * p )                  { return Vec_IntSize(&p->vWires)/WIRE_NUM;          } +static inline int         Rtl_NtkCellNum( Rtl_Ntk_t * p )                  { return Vec_IntSize(&p->vCells);                   } +static inline int         Rtl_NtkConNum( Rtl_Ntk_t * p )                   { return Vec_IntSize(&p->vConns)/2;                 } +static inline int         Rtl_NtkObjNum( Rtl_Ntk_t * p )                   { return p->nInputs + p->nOutputs + Rtl_NtkCellNum(p) + Rtl_NtkConNum(p); } + +static inline int *       Rtl_NtkWire( Rtl_Ntk_t * p, int i )              { return Vec_IntEntryP(&p->vWires, WIRE_NUM*i);                  } +static inline int *       Rtl_NtkCell( Rtl_Ntk_t * p, int i )              { return Vec_IntEntryP(&p->vStore, Vec_IntEntry(&p->vCells, i)); } +static inline int *       Rtl_NtkCon( Rtl_Ntk_t * p, int i )               { return Vec_IntEntryP(&p->vConns, 2*i);                         } + +static inline int         Rtl_WireName( Rtl_Ntk_t * p, int i )             { return Vec_IntEntry(&p->vWires, WIRE_NUM*i) >> 4; } +static inline char *      Rtl_WireNameStr( Rtl_Ntk_t * p, int i )          { return Rtl_NtkStr(p, Rtl_WireName(p, i));         } +static inline int         Rtl_WireFirst( Rtl_Ntk_t * p, int i )            { return Vec_IntEntry(&p->vWires, WIRE_NUM*i);      } +static inline int         Rtl_WireWidth( Rtl_Ntk_t * p, int i )            { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+1);    } +static inline int         Rtl_WireOffset( Rtl_Ntk_t * p, int i )           { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+2);    } +static inline int         Rtl_WireNumber( Rtl_Ntk_t * p, int i )           { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+3);    } +static inline int         Rtl_WireBitStart( Rtl_Ntk_t * p, int i )         { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+4);    } +static inline int         Rtl_WireMapNameToId( Rtl_Ntk_t * p, int i )      { return Vec_IntEntry(p->pLib->vMap, i);            } + +static inline int         Rtl_CellType( int * pCell )                      { return pCell[0];                                  } +static inline int         Rtl_CellName( int * pCell )                      { return pCell[1];                                  } +static inline int         Rtl_CellModule( int * pCell )                    { return pCell[2];                                  } +static inline int         Rtl_CellInputNum( int * pCell )                  { return pCell[3];                                  } +static inline int         Rtl_CellOutputNum( int * pCell )                 { return pCell[6]-pCell[3];                         } +static inline int         Rtl_CellAttrNum( int * pCell )                   { return pCell[4];                                  } +static inline int         Rtl_CellParamNum( int * pCell )                  { return pCell[5];                                  } +static inline int         Rtl_CellConNum( int * pCell )                    { return pCell[6];                                  } +static inline int         Rtl_CellMark( int * pCell )                      { return pCell[7];                                  } +static inline Rtl_Ntk_t * Rtl_CellNtk( Rtl_Ntk_t * p, int * pCell )        { return Rtl_CellModule(pCell) >= ABC_INFINITY ? Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY) : NULL; } + +static inline char *      Rtl_CellTypeStr( Rtl_Ntk_t * p, int * pCell )    { return Rtl_NtkStr(p, Rtl_CellType(pCell));        } +static inline char *      Rtl_CellNameStr( Rtl_Ntk_t * p, int * pCell )    { return Rtl_NtkStr(p, Rtl_CellName(pCell));        } + +static inline int         Rtl_SigIsNone( int s )                           { return (s & 0x3) == 0;                            } +static inline int         Rtl_SigIsConst( int s )                          { return (s & 0x3) == 1;                            } +static inline int         Rtl_SigIsSlice( int s )                          { return (s & 0x3) == 2;                            } +static inline int         Rtl_SigIsConcat( int s )                         { return (s & 0x3) == 3;                            } + +#define Rtl_NtkForEachAttr( p, Par, Val, i ) \ +    for ( i = 0; i < Rtl_NtkAttrNum(p) && (Par = Vec_IntEntry(&p->vAttrs, 2*i)) && (Val = Vec_IntEntry(&p->vAttrs, 2*i+1)); i++ ) +#define Rtl_NtkForEachWire( p, pWire, i ) \ +    for ( i = 0; i < Rtl_NtkWireNum(p) && (pWire = Vec_IntEntryP(&p->vWires, WIRE_NUM*i)); i++ ) +#define Rtl_NtkForEachCell( p, pCell, i ) \ +    for ( i = 0; i < Rtl_NtkCellNum(p) && (pCell = Rtl_NtkCell(p, i)); i++ ) +#define Rtl_NtkForEachCon( p, pCon, i ) \ +    for ( i = 0; i < Rtl_NtkConNum(p) && (pCon = Vec_IntEntryP(&p->vConns, 2*i)); i++ ) + +#define Rtl_CellForEachAttr( p, pCell, Par, Val, i ) \ +    for ( i = 0; i < pCell[4] && (Par = pCell[CELL_NUM+2*i]) && (Val = pCell[CELL_NUM+2*i+1]); i++ ) +#define Rtl_CellForEachParam( p, pCell, Par, Val, i ) \ +    for ( i = 0; i < pCell[5] && (Par = pCell[CELL_NUM+2*(pCell[4]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+i)+1]); i++ ) +#define Rtl_CellForEachConnect( p, pCell, Par, Val, i ) \ +    for ( i = 0; i < pCell[6] && (Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)+1]); i++ ) + +#define Rtl_CellForEachInput( p, pCell, Par, Val, i ) \ +    Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i >= Rtl_CellInputNum(pCell) ) continue; else +#define Rtl_CellForEachOutput( p, pCell, Par, Val, i ) \ +    Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i <  Rtl_CellInputNum(pCell) ) continue; else + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Rtl_Ntk_t * Rtl_NtkAlloc( Rtl_Lib_t * pLib ) +{ +    Rtl_Ntk_t * p = ABC_CALLOC( Rtl_Ntk_t, 1 ); +    Vec_IntGrow( &p->vWires, 4 ); +    Vec_IntGrow( &p->vCells, 4 ); +    Vec_IntGrow( &p->vConns, 4 ); +    Vec_IntGrow( &p->vStore, 8 ); +    Vec_IntGrow( &p->vAttrs, 8 ); +    Vec_PtrPush( pLib->vNtks, (void *)p ); +    p->pLib = pLib; +    return p; +} +void Rtl_NtkFree( Rtl_Ntk_t * p ) +{ +    Gia_ManStopP( &p->pGia ); +    ABC_FREE( p->vWires.pArray ); +    ABC_FREE( p->vCells.pArray ); +    ABC_FREE( p->vConns.pArray ); +    ABC_FREE( p->vStore.pArray ); +    ABC_FREE( p->vAttrs.pArray ); +    ABC_FREE( p->vOrder.pArray ); +    ABC_FREE( p->vLits.pArray ); +    ABC_FREE( p->vBitTemp.pArray ); +    ABC_FREE( p ); +} +void Rtl_NtkCountPio( Rtl_Ntk_t * p, int Counts[4] ) +{ +    int i, * pWire; +    Rtl_NtkForEachWire( p, pWire, i ) +    { +        if ( pWire[0] & 1 ) // PI +            Counts[0]++, Counts[1] += pWire[1]; +        if ( pWire[0] & 2 ) // PO +            Counts[2]++, Counts[3] += pWire[1]; +    } +    assert( p->nInputs  == Counts[0] ); +    assert( p->nOutputs == Counts[2] ); +} +void Rtl_NtkPrintOpers( Rtl_Ntk_t * p ) +{ +    int i, * pCell, nBlack = 0, nUser = 0, Counts[ABC_OPER_LAST] = {0}; +    if ( Rtl_NtkCellNum(p) == 0 ) +        return; +    Rtl_NtkForEachCell( p, pCell, i ) +        if ( Rtl_CellModule(pCell) < ABC_OPER_LAST ) +            Counts[Rtl_CellModule(pCell)]++; +        else if ( Rtl_CellModule(pCell) == ABC_OPER_LAST-1 ) +            nBlack++; +        else +            nUser++; +    printf( "There are %d instances in this network:\n", Rtl_NtkCellNum(p) ); +    if ( nBlack ) +        printf( "  %s (%d)", "blackbox", nBlack ); +    if ( nUser ) +        printf( "  %s (%d)", "user", nUser ); +    for ( i = 0; i < ABC_OPER_LAST; i++ ) +        if ( Counts[i] ) +            printf( "  %s (%d)", Abc_OperName(i), Counts[i] ); +    printf( "\n" ); +} +void Rtl_NtkPrintStats( Rtl_Ntk_t * p, int nNameSymbs ) +{ +    int Counts[4] = {0};     Rtl_NtkCountPio( p, Counts ); +    printf( "%*s : ",        nNameSymbs, Rtl_NtkName(p) ); +    printf( "PI = %3d (%3d)  ", Counts[0], Counts[1] ); +    printf( "PO = %3d (%3d)  ", Counts[2], Counts[3] ); +    printf( "Wire = %6d   ", Rtl_NtkWireNum(p) ); +    printf( "Cell = %6d   ", Rtl_NtkCellNum(p) ); +    printf( "Con = %6d",     Rtl_NtkConNum(p) ); +    printf( "\n" ); +    //Rtl_NtkPrintOpers( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Rtl_Lib_t * Rtl_LibAlloc() +{ +    Rtl_Lib_t * p = ABC_CALLOC( Rtl_Lib_t, 1 ); +    p->vNtks = Vec_PtrAlloc( 100 ); +    Vec_IntGrow( &p->vConsts,  1000 ); +    Vec_IntGrow( &p->vSlices,  1000 ); +    Vec_IntGrow( &p->vConcats, 1000 ); +    return p; +} +void Rtl_LibFree( Rtl_Lib_t * p ) +{ +    Rtl_Ntk_t * pNtk; int i; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        Rtl_NtkFree( pNtk );     +    ABC_FREE( p->vConsts.pArray ); +    ABC_FREE( p->vSlices.pArray ); +    ABC_FREE( p->vConcats.pArray ); +    ABC_FREE( p->vAttrTemp.pArray ); +    for ( i = 0; i < TEMP_NUM; i++ ) +        ABC_FREE( p->vTemp[i].pArray ); +    Vec_IntFreeP( &p->vMap ); +    Vec_IntFreeP( &p->vTokens ); +    Abc_NamStop( p->pManName ); +    Vec_PtrFree( p->vNtks ); +    ABC_FREE( p->pSpec ); +    ABC_FREE( p ); +} +int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId ) +{ +    Rtl_Ntk_t * pNtk; int i; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        if ( pNtk->NameId == NameId ) +            return i; +    return -1; +} +void Rtl_LibPrintStats( Rtl_Lib_t * p ) +{ +    Rtl_Ntk_t * pNtk; int i, nSymbs = 0; +    printf( "Modules found in \"%s\":\n", p->pSpec ); +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        nSymbs = Abc_MaxInt( nSymbs, strlen(Rtl_NtkName(pNtk)) ); +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        Rtl_NtkPrintStats( pNtk, nSymbs + 2 );   +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +typedef enum { +    RTL_NONE = 0,  // 0:  unused +    RTL_MODULE,    // 1:  "module" +    RTL_END,       // 2:  "end" +    RTL_INPUT,     // 3:  "input" +    RTL_OUTPUT,    // 4:  "output" +    RTL_INOUT,     // 5:  "inout" +    RTL_UPTO,      // 6:  "upto" +    RTL_SIGNED,    // 7:  "signed" +    RTL_OFFSET,    // 8:  "offset" +    RTL_PARAMETER, // 9:  "parameter" +    RTL_WIRE,      // 10: "wire" +    RTL_CONNECT,   // 11: "connect" +    RTL_CELL,      // 12: "cell" +    RTL_WIDTH,     // 13: "width" +    RTL_ATTRIBUTE, // 14: "attribute" +    RTL_UNUSED     // 15: unused +} Rtl_Type_t;  + +static inline char * Rtl_Num2Name( int i ) +{ +    if ( i == 1  )  return "module"; +    if ( i == 2  )  return "end"; +    if ( i == 3  )  return "input"; +    if ( i == 4  )  return "output"; +    if ( i == 5  )  return "inout"; +    if ( i == 6  )  return "upto"; +    if ( i == 7  )  return "signed"; +    if ( i == 8  )  return "offset"; +    if ( i == 9  )  return "parameter"; +    if ( i == 10 )  return "wire"; +    if ( i == 11 )  return "connect"; +    if ( i == 12 )  return "cell"; +    if ( i == 13 )  return "width"; +    if ( i == 14 )  return "attribute"; +    return NULL; +} + +static inline void Rtl_LibDeriveMap( Rtl_Lib_t * p ) +{ +    int i; +    p->pMap[0] = -1; +    for ( i = 1; i < RTL_UNUSED; i++ ) +        p->pMap[i] = Abc_NamStrFind( p->pManName, Rtl_Num2Name(i) ); +} + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Rtl_LibReadType( char * pType ) +{ +    if ( !strcmp(pType, "$not") )         return ABC_OPER_BIT_INV;       // Y = ~A       $not             +    if ( !strcmp(pType, "$pos") )         return ABC_OPER_BIT_BUF;       // Y = +A       $pos             +    if ( !strcmp(pType, "$neg") )         return ABC_OPER_ARI_MIN;       // Y = -A       $neg             +    if ( !strcmp(pType, "$reduce_and") )  return ABC_OPER_RED_AND;       // Y = &A       $reduce_and      +    if ( !strcmp(pType, "$reduce_or") )   return ABC_OPER_RED_OR;        // Y = |A       $reduce_or       +    if ( !strcmp(pType, "$reduce_xor") )  return ABC_OPER_RED_XOR;       // Y = ^A       $reduce_xor      +    if ( !strcmp(pType, "$reduce_xnor") ) return ABC_OPER_RED_NXOR;      // Y = ~^A      $reduce_xnor    +    if ( !strcmp(pType, "$reduce_bool") ) return ABC_OPER_RED_OR;        // Y = |A       $reduce_bool     +    if ( !strcmp(pType, "$logic_not") )   return ABC_OPER_LOGIC_NOT;     // Y = !A       $logic_not       + +    if ( !strcmp(pType, "$and") )         return ABC_OPER_BIT_AND;       // Y = A & B    $and          +    if ( !strcmp(pType, "$or") )          return ABC_OPER_BIT_OR;        // Y = A | B    $or           +    if ( !strcmp(pType, "$xor") )         return ABC_OPER_BIT_XOR;       // Y = A ^ B    $xor          +    if ( !strcmp(pType, "$xnor") )        return ABC_OPER_BIT_NXOR;      // Y = A ~^ B   $xnor     +     +    if ( !strcmp(pType, "$shl") )         return ABC_OPER_SHIFT_L;       // Y = A << B   $shl         +    if ( !strcmp(pType, "$shr") )         return ABC_OPER_SHIFT_R;       // Y = A >> B   $shr         +    if ( !strcmp(pType, "$sshl") )        return ABC_OPER_SHIFT_LA;      // Y = A <<< B  $sshl       +    if ( !strcmp(pType, "$sshr") )        return ABC_OPER_SHIFT_RA;      // Y = A >>> B  $sshr       + +    if ( !strcmp(pType, "$shiftx") )      return ABC_OPER_SHIFT_R;       // Y = A << B   $shl     <== temporary    + +    if ( !strcmp(pType, "$logic_and") )   return ABC_OPER_LOGIC_AND;     // Y = A && B   $logic_and   +    if ( !strcmp(pType, "$logic_or") )    return ABC_OPER_LOGIC_OR;      // Y = A || B   $logic_or   +     +    if ( !strcmp(pType, "$lt") )          return ABC_OPER_COMP_LESS;     // Y = A < B    $lt           +    if ( !strcmp(pType, "$le") )          return ABC_OPER_COMP_LESSEQU;  // Y = A <= B   $le          +    if ( !strcmp(pType, "$ge") )          return ABC_OPER_COMP_MOREEQU;  // Y = A >= B   $ge            +    if ( !strcmp(pType, "$gt") )          return ABC_OPER_COMP_MORE;     // Y = A > B    $gt         +    if ( !strcmp(pType, "$eq") )          return ABC_OPER_COMP_EQU;      // Y = A == B   $eq          +    if ( !strcmp(pType, "$ne") )          return ABC_OPER_COMP_NOTEQU;   // Y = A != B   $ne          +    if ( !strcmp(pType, "$eqx") )         return ABC_OPER_COMP_EQU;      // Y = A === B  $eqx        +    if ( !strcmp(pType, "$nex") )         return ABC_OPER_COMP_NOTEQU;   // Y = A !== B  $nex        +     +    if ( !strcmp(pType, "$add") )         return ABC_OPER_ARI_ADD;       // Y = A + B    $add          +    if ( !strcmp(pType, "$sub") )         return ABC_OPER_ARI_SUB;       // Y = A - B    $sub          +    if ( !strcmp(pType, "$mul") )         return ABC_OPER_ARI_MUL;       // Y = A * B    $mul          +    if ( !strcmp(pType, "$div") )         return ABC_OPER_ARI_DIV;       // Y = A / B    $div          +    if ( !strcmp(pType, "$mod") )         return ABC_OPER_ARI_MOD;       // Y = A % B    $mod          +    if ( !strcmp(pType, "$pow") )         return ABC_OPER_ARI_POW;       // Y = A ** B   $pow         + +    if ( !strcmp(pType, "$modfoor") )     return ABC_OPER_NONE;          // [N/A] $modfoor          +    if ( !strcmp(pType, "$divfloor") )    return ABC_OPER_NONE;          // [N/A] $divfloor         + +    if ( !strcmp(pType, "$mux") )         return ABC_OPER_SEL_NMUX;      // $mux                    +    if ( !strcmp(pType, "$pmux") )        return ABC_OPER_SEL_SEL;       // $pmux                   +                                                                +    if ( !strcmp(pType, "$dff") )         return ABC_OPER_DFF; +    if ( !strcmp(pType, "$adff") )        return ABC_OPER_DFF; +    if ( !strcmp(pType, "$sdff") )        return ABC_OPER_DFF; +    assert( 0 );                                                +    return -1;                                                  +}                                                                          +int Rtl_NtkReadType( Rtl_Ntk_t * p, int Type )                                                                          +{                                                                          +    extern int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId ); +    char * pType = Rtl_NtkStr( p, Type );                    +    if ( pType[0] == '$' && strncmp(pType,"$paramod",strlen("$paramod")) ) +        return Rtl_LibReadType( pType );                     +    return ABC_INFINITY + Rtl_LibFindModule( p->pLib, Type ); +}                                                            +                                                             +/**Function************************************************************* +                                                             +  Synopsis    [There is no need to normalize ranges in Yosys.] +                                                             +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Rtl_NtkRangeWires( Rtl_Ntk_t * p ) +{ +    int i, * pWire, nBits = 0; +    Rtl_NtkForEachWire( p, pWire, i ) +    { +        //printf( "%s -> %d\n", Rtl_WireNameStr(p, i), nBits ); +        pWire[4] = nBits, nBits += Rtl_WireWidth(p, i); +    } +    return nBits; +} +void Rtl_NtkMapWires( Rtl_Ntk_t * p, int fUnmap ) +{ +    int i, Value; +    assert( Vec_IntSize(p->pLib->vMap) == Abc_NamObjNumMax(p->pLib->pManName) ); +    for ( i = 0; i < Rtl_NtkWireNum(p); i++ ) +    { +        int NameId = Rtl_WireName( p, i ); +        assert( Vec_IntEntry(p->pLib->vMap, NameId) == (fUnmap ? i : -1) ); +        Vec_IntWriteEntry( p->pLib->vMap, NameId, fUnmap ? -1 : i ); +    } +    if ( fUnmap ) +        Vec_IntForEachEntry( p->pLib->vMap, Value, i ) +            assert( Value == -1 ); +} +void Rtl_NtkNormRanges( Rtl_Ntk_t * p ) +{ +    int i, * pWire; +    Rtl_NtkMapWires( p, 0 ); +    for ( i = p->Slice0; i < p->Slice1; i += 3 ) +    { +        int NameId = Vec_IntEntry( &p->pLib->vSlices, i ); +        int Left   = Vec_IntEntry( &p->pLib->vSlices, i+1 ); +        int Right  = Vec_IntEntry( &p->pLib->vSlices, i+2 ); +        int Wire   = Rtl_WireMapNameToId( p, NameId ); +        int Offset = Rtl_WireOffset( p, Wire ); +        int First  = Rtl_WireFirst( p, Wire ); +        assert( First >> 4 == NameId ); +        if ( Offset ); +        { +            Left  -= Offset; +            Right -= Offset; +        } +        if ( First & 8 ) // upto +        { +            Vec_IntWriteEntry( &p->pLib->vSlices, i+1, Right ); +            Vec_IntWriteEntry( &p->pLib->vSlices, i+2, Left ); +        } +    } +    Rtl_NtkForEachWire( p, pWire, i ) +    { +        Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+0, Rtl_WireFirst(p, i) & ~0x8 ); // upto +        Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+2, 0 ); // offset +    } +    Rtl_NtkMapWires( p, 1 ); +} +void Rtl_LibNormRanges( Rtl_Lib_t * pLib ) +{ +    Rtl_Ntk_t * p; int i; +    if ( pLib->vMap == NULL ) +        pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) ); +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) +        Rtl_NtkNormRanges( p );     +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int * Rlt_NtkFindIOPerm( Rtl_Ntk_t * p ) +{ +    Vec_Int_t * vCost = Vec_IntAlloc( 100 ); +    int i, * pWire, * pPerm = NULL, Count = 0; +    Rtl_NtkForEachWire( p, pWire, i ) +    { +        int First  = Rtl_WireFirst( p, i ); +        int Number = Rtl_WireNumber( p, i ); +        int fIsPi  = (int)((First & 1) > 0); +        int fIsPo  = (int)((First & 2) > 0); +        assert( (fIsPi || fIsPo) == (Number > 0) ); +        if ( fIsPi || fIsPo ) +            Vec_IntPush( vCost, fIsPo*ABC_INFINITY + Number ); +        else +            Vec_IntPush( vCost, 2*ABC_INFINITY + Count++ ); +    } +    pPerm = Abc_MergeSortCost( Vec_IntArray(vCost), Vec_IntSize(vCost) ); +    Vec_IntFree( vCost ); +    return pPerm; +} +void Rtl_NtkOrderWires( Rtl_Ntk_t * p ) +{ +    Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(&p->vWires) ); +    int i, k, * pWire, * pPerm = Rlt_NtkFindIOPerm( p ); +    Rtl_NtkForEachWire( p, pWire, i ) +    { +        pWire = Vec_IntEntryP( &p->vWires, WIRE_NUM*pPerm[i] ); +        for ( k = 0; k < WIRE_NUM; k++ ) +            Vec_IntPush( vTemp, pWire[k] ); +    } +    ABC_FREE( pPerm ); +    assert( Vec_IntSize(&p->vWires) == Vec_IntSize(vTemp) ); +    ABC_SWAP( Vec_Int_t, p->vWires, *vTemp );  +    Vec_IntFree( vTemp ); +} +void Rtl_LibUpdateInstances( Rtl_Ntk_t * p ) +{ +    Vec_Int_t * vMap  = p->pLib->vMap; +    Vec_Int_t * vTemp = &p->pLib->vTemp[2]; +    int i, k, Par, Val, * pCell, Value; +    Rtl_NtkForEachCell( p, pCell, i ) +        if ( Rtl_CellModule(pCell) >= ABC_INFINITY ) +        { +            Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); +            assert( pCell[6] == pModel->nInputs+pModel->nOutputs ); +            Rtl_CellForEachConnect( p, pCell, Par, Val, k ) +                Vec_IntWriteEntry( vMap, Par >> 2, k ); +            Vec_IntClear( vTemp ); +            for ( k = 0; k < pCell[6]; k++ ) +            { +                int Perm = Vec_IntEntry( vMap, Rtl_WireName(pModel, k) ); +                int Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)]; +                int Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)+1]; +                assert( (Par >> 2) == Rtl_WireName(pModel, k) ); +                Vec_IntWriteEntry( vMap, Par >> 2, -1 ); +                Vec_IntPushTwo( vTemp, Par, Val ); +                assert( Perm >= 0 ); +            } +            memcpy( pCell+CELL_NUM+2*(pCell[4]+pCell[5]), Vec_IntArray(vTemp), sizeof(int)*Vec_IntSize(vTemp) ); +        } +    Vec_IntForEachEntry( p->pLib->vMap, Value, i ) +        assert( Value == -1 ); +} +void Rtl_LibOrderWires( Rtl_Lib_t * pLib ) +{ +    Rtl_Ntk_t * p; int i; +    if ( pLib->vMap == NULL ) +        pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) ); +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) +        Rtl_NtkOrderWires( p );     +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) +        Rtl_LibUpdateInstances( p );     +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +extern int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig ); + +int Rtl_NtkCountWireRange( Rtl_Ntk_t * p, int NameId ) +{ +    int Wire  = Rtl_WireMapNameToId( p, NameId ); +    int Width = Rtl_WireWidth( p, Wire ); +    return Width; +} +int Rtl_NtkCountSliceRange( Rtl_Ntk_t * p, int * pSlice ) +{ +    return pSlice[1] - pSlice[2] + 1; +} +int Rtl_NtkCountConcatRange( Rtl_Ntk_t * p, int * pConcat ) +{ +    int i, nBits = 0; +    for ( i = 1; i <= pConcat[0]; i++ ) +        nBits += Rtl_NtkCountSignalRange( p, pConcat[i] ); +    return nBits; +} +int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig ) +{ +    if ( Rtl_SigIsNone(Sig) ) +        return Rtl_NtkCountWireRange( p, Sig >> 2 ); +    if ( Rtl_SigIsSlice(Sig) ) +        return Rtl_NtkCountSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); +    if ( Rtl_SigIsConcat(Sig) ) +        return Rtl_NtkCountConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); +    if ( Rtl_SigIsConst(Sig) ) +        assert( 0 ); +    return ABC_INFINITY; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +extern int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig ); + +int Rtl_NtkCheckWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right ) +{ +    int Wire  = Rtl_WireMapNameToId( p, NameId ); +    int First = Rtl_WireBitStart( p, Wire ); +    int Width = Rtl_WireWidth( p, Wire ), i; +    Left  = Left  == -1 ? Width-1 :  Left; +    Right = Right == -1 ? 0       : Right; +    assert ( Right <= Left && Right >= 0 ); +    for ( i = Right; i <= Left; i++ ) +        if ( Vec_IntEntry(&p->vLits, First+i) == -1 ) +            return 0; +    return 1; +} +int Rtl_NtkCheckSliceRange( Rtl_Ntk_t * p, int * pSlice ) +{ +    return Rtl_NtkCheckWireRange( p, pSlice[0], pSlice[1], pSlice[2] ); +} +int Rtl_NtkCheckConcatRange( Rtl_Ntk_t * p, int * pConcat ) +{ +    int i; +    for ( i = 1; i <= pConcat[0]; i++ ) +        if ( !Rtl_NtkCheckSignalRange( p, pConcat[i] ) ) +            return 0; +    return 1; +} +int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig ) +{ +    if ( Rtl_SigIsNone(Sig) ) +        return Rtl_NtkCheckWireRange( p, Sig >> 2, -1, -1 ); +    else if ( Rtl_SigIsConst(Sig) ) +        return 1; +    else if ( Rtl_SigIsSlice(Sig) ) +        return Rtl_NtkCheckSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); +    else if ( Rtl_SigIsConcat(Sig) ) +        return Rtl_NtkCheckConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); +    else assert( 0 ); +    return -1; +} + + +extern void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value ); + +void Rtl_NtkSetWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int Value ) +{ +    //char * pName = Rtl_NtkStr( p, NameId ); +    int Wire  = Rtl_WireMapNameToId( p, NameId ); +    int First = Rtl_WireBitStart( p, Wire ); +    int Width = Rtl_WireWidth( p, Wire ), i; +    Left  = Left  == -1 ? Width-1 :  Left; +    Right = Right == -1 ? 0       : Right; +    assert ( Right <= Left && Right >= 0 ); +    for ( i = Right; i <= Left; i++ ) +    { +        assert( Vec_IntEntry(&p->vLits, First+i) == -1 ); +        Vec_IntWriteEntry(&p->vLits, First+i, Value ); +    } +    //printf( "Finished setting wire %s\n", Rtl_NtkStr(p, NameId) ); +} +void Rtl_NtkSetSliceRange( Rtl_Ntk_t * p, int * pSlice, int Value ) +{ +    Rtl_NtkSetWireRange( p, pSlice[0], pSlice[1], pSlice[2], Value ); +} +void Rtl_NtkSetConcatRange( Rtl_Ntk_t * p, int * pConcat, int Value ) +{ +    int i; +    for ( i = 1; i <= pConcat[0]; i++ ) +        Rtl_NtkSetSignalRange( p, pConcat[i], Value ); +} +void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value ) +{ +    if ( Rtl_SigIsNone(Sig) ) +        Rtl_NtkSetWireRange( p, Sig >> 2, -1, -1, Value ); +    else if ( Rtl_SigIsSlice(Sig) ) +        Rtl_NtkSetSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), Value ); +    else if ( Rtl_SigIsConcat(Sig) ) +        Rtl_NtkSetConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), Value ); +    else if ( Rtl_SigIsConst(Sig) ) +        assert( 0 ); +} + + +void Rtl_NtkInitInputs( Rtl_Ntk_t * p ) +{ +    int b, i; +    for ( i = 0; i < p->nInputs; i++ ) +    { +        int First = Rtl_WireBitStart( p, i ); +        int Width = Rtl_WireWidth( p, i ); +        for ( b = 0; b < Width; b++ ) +        { +            assert( Vec_IntEntry(&p->vLits, First+b) == -1 ); +            Vec_IntWriteEntry( &p->vLits, First+b, Vec_IntSize(&p->vOrder) ); +        } +        Vec_IntPush( &p->vOrder, i ); +        //printf( "Finished setting input %s\n", Rtl_WireNameStr(p, i) ); +    } +} +Vec_Int_t * Rtl_NtkCollectOutputs( Rtl_Ntk_t * p ) +{ +    //char * pNtkName = Rtl_NtkName(p); +    int b, i; +    Vec_Int_t * vRes = Vec_IntAlloc( 100 ); +    for ( i = 0; i < p->nOutputs; i++ ) +    { +        //char * pName = Rtl_WireNameStr(p, p->nInputs + i); +        int First = Rtl_WireBitStart( p, p->nInputs + i ); +        int Width = Rtl_WireWidth( p, p->nInputs + i ); +        for ( b = 0; b < Width; b++ ) +        { +            assert( Vec_IntEntry(&p->vLits, First+b) != -1 ); +            Vec_IntPush( vRes, Vec_IntEntry(&p->vLits, First+b) ); +        } +    } +    return vRes; +} +int Rtl_NtkReviewCells( Rtl_Ntk_t * p ) +{ +    int i, k, Par, Val, * pCell, RetValue = 0; +    Rtl_NtkForEachCell( p, pCell, i ) +    { +        if ( pCell[7] ) +            continue; +        Rtl_CellForEachInput( p, pCell, Par, Val, k ) +            if ( !Rtl_NtkCheckSignalRange( p, Val ) ) +                break; +        if ( k < Rtl_CellInputNum(pCell) ) +            continue; +        Rtl_CellForEachOutput( p, pCell, Par, Val, k ) +            Rtl_NtkSetSignalRange( p, Val, Vec_IntSize(&p->vOrder) ); +        Vec_IntPush( &p->vOrder, p->nInputs + i ); +        pCell[7] = 1; +        RetValue = 1; +        //printf( "Setting cell %s as propagated.\n", Rtl_CellNameStr(p, pCell) ); +    } +    return RetValue; +} +int Rtl_NtkReviewConnections( Rtl_Ntk_t * p ) +{ +    int i, * pCon, RetValue = 0; +    Rtl_NtkForEachCon( p, pCon, i ) +    { +        int Status0 = Rtl_NtkCheckSignalRange( p, pCon[0] ); +        int Status1 = Rtl_NtkCheckSignalRange( p, pCon[1] ); +        if ( Status0 == Status1 ) +            continue; +        if ( !Status0 && Status1 ) +            ABC_SWAP( int, pCon[0], pCon[1] ) +        Rtl_NtkSetSignalRange( p, pCon[1], Vec_IntSize(&p->vOrder) ); +        Vec_IntPush( &p->vOrder, p->nInputs + Rtl_NtkCellNum(p) + i ); +        RetValue = 1; +    } +    return RetValue; +} +void Rtl_NtkPrintCellOrder( Rtl_Ntk_t * p ) +{ +    int i, iCell; +    Vec_IntForEachEntry( &p->vOrder, iCell, i ) +    { +        printf( "%4d :  ", i ); +        printf( "Cell %4d  ", iCell ); +        if ( iCell < p->nInputs ) +            printf( "Type  Input " ); +        else if ( iCell < p->nInputs + Rtl_NtkCellNum(p) ) +        { +            int * pCell = Rtl_NtkCell( p, iCell - p->nInputs ); +            printf( "Type  %4d  ", Rtl_CellType(pCell) ); +            printf( "%16s ",       Rtl_CellTypeStr(p, pCell) ); +            printf( "%16s ",       Rtl_CellNameStr(p, pCell) ); +        } +        else +            printf( "Type  Connection " ); +        printf( "\n" ); +    } +} +void Rtl_NtkPrintUnusedCells( Rtl_Ntk_t * p ) +{ +    int i, * pCell; +    printf( "\n*** Printing unused cells:\n" ); +    Rtl_NtkForEachCell( p, pCell, i ) +    { +        if ( pCell[7] ) +            continue; +        printf( "Unused cell %s           %s\n", Rtl_CellTypeStr(p, pCell), Rtl_CellNameStr(p, pCell) ); +    } +    printf( "\n" ); +} +void Rtl_NtkOrderCells( Rtl_Ntk_t * p ) +{ +    Vec_Int_t * vRes; +    int nBits = Rtl_NtkRangeWires( p ); +    Vec_IntFill( &p->vLits, nBits, -1 ); + +    Vec_IntClear( &p->vOrder ); +    Vec_IntGrow( &p->vOrder, Rtl_NtkObjNum(p) ); +    Rtl_NtkInitInputs( p ); + +    Rtl_NtkMapWires( p, 0 ); +//Vec_IntPrint(&p->vLits); + +    Rtl_NtkReviewConnections( p ); +    while ( Rtl_NtkReviewCells(p) | Rtl_NtkReviewConnections(p) ); +    Rtl_NtkMapWires( p, 1 ); + +    vRes = Rtl_NtkCollectOutputs( p ); +    Vec_IntFree( vRes ); + +    //Rtl_NtkPrintCellOrder( p ); +} +void Rtl_LibOrderCells( Rtl_Lib_t * pLib ) +{ +    Rtl_Ntk_t * p; int i; +    if ( pLib->vMap == NULL ) +        pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) ); +    assert( Vec_IntSize(pLib->vMap) == Abc_NamObjNumMax(pLib->pManName) ); +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) +        Rtl_NtkOrderCells( p );     +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rtl_TokenUnspace( char * p ) +{ +    int i, Length = strlen(p), Quote = 0; +    for ( i = 0; i < Length; i++ ) +        if ( p[i] == '\"' ) +            Quote ^= 1; +        else if ( Quote && p[i] == ' ' ) +            p[i] = '\"'; +} +void Rtl_TokenRespace( char * p ) +{ +    int i, Length = strlen(p); +    assert( p[0] == '\"' && p[Length-1] == '\"' ); +    for ( i = 1; i < Length-1; i++ ) +        if ( p[i] == '\"' ) +            p[i] = ' '; +} +Vec_Int_t * Rtl_NtkReadFile( char * pFileName, Abc_Nam_t * p ) +{ +    Vec_Int_t * vTokens; +    char * pTemp, Buffer[MAX_LINE];  +    FILE * pFile = fopen( pFileName, "rb" ); +    if ( pFile == NULL ) +    { +        printf( "Cannot open file \"%s\" for reading.\n", pFileName ); +        return NULL; +    } +    Abc_NamStrFindOrAdd( p, "module", NULL ); +    assert( Abc_NamObjNumMax(p) == 2 ); +    vTokens = Vec_IntAlloc( 1000 ); +    while ( fgets( Buffer, MAX_LINE, pFile ) != NULL ) +    { +        if ( Buffer[0] == '#' ) +            continue; +        Rtl_TokenUnspace( Buffer ); +        pTemp = strtok( Buffer, " \t\r\n" ); +        if ( pTemp == NULL ) +            continue; +        while ( pTemp ) +        { +            if ( *pTemp == '\"' )  Rtl_TokenRespace( pTemp ); +            Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, pTemp, NULL) ); +            pTemp = strtok( NULL, " \t\r\n" ); +        } +        Vec_IntPush( vTokens, -1 ); +    } +    fclose( pFile ); +    return vTokens; +} + + + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +extern void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig ); + +void Rtl_NtkPrintConst( Rtl_Ntk_t * p, int * pConst ) +{ +    int i; +    if ( pConst[0] == -1 ) +    { +        fprintf( Rtl_NtkFile(p), " %d", pConst[1] ); +        return; +    } +    fprintf( Rtl_NtkFile(p), " %d\'", pConst[0] ); +    for ( i = pConst[0] - 1; i >= 0; i-- ) +        fprintf( Rtl_NtkFile(p), "%d", Abc_InfoHasBit(pConst+1,i) ); +} +void Rtl_NtkPrintSlice( Rtl_Ntk_t * p, int * pSlice ) +{ +    fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, pSlice[0]) ); +    if ( pSlice[1] == pSlice[2] ) +        fprintf( Rtl_NtkFile(p), " [%d]", pSlice[1] ); +    else +        fprintf( Rtl_NtkFile(p), " [%d:%d]", pSlice[1], pSlice[2] ); +} +void Rtl_NtkPrintConcat( Rtl_Ntk_t * p, int * pConcat ) +{ +    int i; +    fprintf( Rtl_NtkFile(p), " {" ); +    for ( i = 1; i <= pConcat[0]; i++ ) +        Rtl_NtkPrintSig( p, pConcat[i] ); +    fprintf( Rtl_NtkFile(p), " }" ); +} +void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig ) +{ +    if ( Rtl_SigIsNone(Sig) ) +        fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, Sig >> 2) ); +    else if ( Rtl_SigIsConst(Sig) ) +        Rtl_NtkPrintConst( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) ); +    else if ( Rtl_SigIsSlice(Sig) ) +        Rtl_NtkPrintSlice( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); +    else if ( Rtl_SigIsConcat(Sig) ) +        Rtl_NtkPrintConcat( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); +    else assert( 0 ); +} +void Rtl_NtkPrintWire( Rtl_Ntk_t * p, int * pWire ) +{ +    fprintf( Rtl_NtkFile(p), "  wire" ); +    if ( pWire[1] != 1 )  fprintf( Rtl_NtkFile(p), " width %d",  pWire[1] ); +    if ( pWire[2] != 0 )  fprintf( Rtl_NtkFile(p), " offset %d", pWire[2] ); +    if ( pWire[0] & 8 )   fprintf( Rtl_NtkFile(p), " upto" ); +    if ( pWire[0] & 1 )   fprintf( Rtl_NtkFile(p), " input %d",  pWire[3] ); +    if ( pWire[0] & 2 )   fprintf( Rtl_NtkFile(p), " output %d", pWire[3] ); +    if ( pWire[0] & 4 )   fprintf( Rtl_NtkFile(p), " signed" ); +    fprintf( Rtl_NtkFile(p), " %s\n", Rtl_NtkStr(p, pWire[0] >> 4) ); +} +void Rtl_NtkPrintCell( Rtl_Ntk_t * p, int * pCell ) +{ +    int i, Par, Val; +    Rtl_CellForEachAttr( p, pCell, Par, Val, i ) +        fprintf( Rtl_NtkFile(p), "  attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) ); +        fprintf( Rtl_NtkFile(p), "  cell %s %s\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkStr(p, pCell[1]) ); +    Rtl_CellForEachParam( p, pCell, Par, Val, i ) +        fprintf( Rtl_NtkFile(p), "    parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" ); +    Rtl_CellForEachConnect( p, pCell, Par, Val, i ) +        fprintf( Rtl_NtkFile(p), "    connect" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" ); +        fprintf( Rtl_NtkFile(p), "  end\n" ); +} +void Rtl_NtkPrintConnection( Rtl_Ntk_t * p, int * pCon ) +{ +    fprintf( Rtl_NtkFile(p), "  connect" ); +    Rtl_NtkPrintSig( p, pCon[0] ); +    Rtl_NtkPrintSig( p, pCon[1] ); +    fprintf( Rtl_NtkFile(p), "\n" ); +} +void Rtl_NtkPrint( Rtl_Ntk_t * p ) +{ +    int i, Par, Val, * pWire, * pCell, * pCon; +    fprintf( Rtl_NtkFile(p), "\n" ); +    Rtl_NtkForEachAttr( p, Par, Val, i ) +        fprintf( Rtl_NtkFile(p), "attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) ); +    fprintf( Rtl_NtkFile(p), "module %s\n", Rtl_NtkName(p) ); +    Rtl_NtkForEachWire( p, pWire, i ) +        Rtl_NtkPrintWire( p, pWire ); +    Rtl_NtkForEachCell( p, pCell, i ) +        Rtl_NtkPrintCell( p, pCell ); +    Rtl_NtkForEachCon( p, pCon, i ) +        Rtl_NtkPrintConnection( p, pCon ); +    fprintf( Rtl_NtkFile(p), "end\n" ); +} +void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p ) +{ +    p->pFile = pFileName ? fopen( pFileName, "wb" ) : stdout; +    if ( p->pFile == NULL ) +    { +        printf( "Cannot open output file \"%s\".\n", pFileName ); +        return; +    } +    else +    { +        Rtl_Ntk_t * pNtk; int i; +        fprintf( p->pFile, "\n" ); +        fprintf( p->pFile, "# Generated by ABC on %s\n", Extra_TimeStamp() ); +        Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +            Rtl_NtkPrint( pNtk );     +        if ( p->pFile != stdout ) +            fclose( p->pFile ); +        p->pFile = NULL; +    } +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +extern int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos ); + +int Rtl_NtkReadConst( Rtl_Ntk_t * p, char * pConst ) +{ +    Vec_Int_t * vConst = &p->pLib->vConsts; +    int RetVal = Vec_IntSize( vConst ); +    int Width  = atoi( pConst ); +    assert( pConst[0] >= '0' && pConst[0] <= '9' ); +    if ( strstr(pConst, "\'") ) +    { +        int Length = strlen(pConst); +        int nWords = (Width + 31) / 32; +        int i, * pArray; +        Vec_IntPush( vConst, Width ); +        Vec_IntFillExtra( vConst, Vec_IntSize(vConst) + nWords, 0 ); +        pArray = Vec_IntEntryP( vConst, RetVal + 1 ); +        for ( i = Length-1; i >= Length-Width; i-- ) +            if ( pConst[i] == '1' ) +                Abc_InfoSetBit( pArray, Length-1-i ); +    } +    else +    { +        Vec_IntPush( vConst, -1 ); +        Vec_IntPush( vConst, Width ); +    } +    return (RetVal << 2) | 1; +} +int Rtl_NtkReadSlice( Rtl_Ntk_t * p, char * pSlice, int NameId ) +{ +    Vec_Int_t * vSlice = &p->pLib->vSlices; +    int RetVal  = Vec_IntSize( vSlice ); +    int Left    = atoi( pSlice+1 ); +    char * pTwo = strstr( pSlice, ":" ); +    int Right   = pTwo ? atoi( pTwo+1 ) : Left; +    assert( pSlice[0] == '[' && pSlice[strlen(pSlice)-1] == ']' ); +    Vec_IntPush( vSlice, NameId ); +    Vec_IntPush( vSlice, Left   ); +    Vec_IntPush( vSlice, Right  ); +    return (RetVal << 2) | 2; +} +int Rtl_NtkReadConcat( Rtl_Ntk_t * p, int * pPos ) +{ +    Vec_Int_t * vConcat = &p->pLib->vConcats; +    int RetVal = Vec_IntSize( vConcat ); char * pTok; +    Vec_IntPush( vConcat, ABC_INFINITY ); +    do { +        int Sig = Rtl_NtkReadSig( p, pPos ); +        Vec_IntPush( vConcat, Sig ); +        pTok = Rtl_NtkTokStr( p, *pPos ); +    }  +    while ( pTok[0] != '}' ); +    Vec_IntWriteEntry( vConcat, RetVal, Vec_IntSize(vConcat) - RetVal - 1 ); +    assert( pTok[0] == '}' ); +    (*pPos)++; +    return (RetVal << 2) | 3; +} +int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos ) +{ +    int NameId  = Rtl_NtkTokId( p, *pPos ); +    char * pSig = Rtl_NtkTokStr( p, (*pPos)++ ); +    if ( pSig[0] >= '0' && pSig[0] <= '9' ) +        return Rtl_NtkReadConst( p, pSig ); +    if ( pSig[0] == '{' ) +        return Rtl_NtkReadConcat( p, pPos ); +    else  +    { +        char * pNext = Rtl_NtkTokStr( p, *pPos ); +        if ( pNext && pNext[0] == '[' ) +        { +            (*pPos)++; +            return Rtl_NtkReadSlice( p, pNext, NameId ); +        } +        else +            return NameId << 2; +    } +} +int Rtl_NtkReadWire( Rtl_Ntk_t * p, int iPos ) +{ +    int i, Entry, Prev = -1; +    int Width = 1, Upto = 0, Offset = 0, Out = 0, In = 0, Number = 0, Signed = 0; +    assert( Rtl_NtkPosCheck(p, iPos-1, RTL_WIRE) ); +    Vec_IntClear( &p->pLib->vAttrTemp ); +    Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos ) +    { +        char * pTok = Rtl_NtkTokStr(p, i); +        if ( Entry == -1 ) +            break; +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_WIDTH) ) +            Width = atoi( Rtl_NtkTokStr(p, ++i) ); +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_OFFSET) ) +            Offset = atoi( Rtl_NtkTokStr(p, ++i) ); +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_INPUT) ) +            Number = atoi( Rtl_NtkTokStr(p, ++i) ), In = 1, p->nInputs++; +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_OUTPUT) ) +            Number = atoi( Rtl_NtkTokStr(p, ++i) ), Out = 1, p->nOutputs++; +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_SIGNED) ) +            Signed = 1; +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_UPTO) ) +            Upto = 1; +        Prev = Entry; +    } +    // add WIRE_NUM=5 entries +    Vec_IntPush( &p->vWires, (Prev << 4) | (Upto << 3) | (Signed << 2) | (Out << 1) | (In << 0) ); +    Vec_IntPush( &p->vWires, Width  ); +    Vec_IntPush( &p->vWires, Offset ); +    Vec_IntPush( &p->vWires, Number ); +    Vec_IntPush( &p->vWires, -1 ); +    assert( Rtl_NtkPosCheck(p, i, RTL_NONE) ); +    return i; +} +int Rtl_NtkReadAttribute( Rtl_Ntk_t * p, int iPos ) +{ +//char * pTok1 = Rtl_NtkTokStr(p, iPos-1); +//char * pTok2 = Rtl_NtkTokStr(p, iPos); +//char * pTok3 = Rtl_NtkTokStr(p, iPos+1); +    assert( Rtl_NtkPosCheck(p, iPos-1, RTL_ATTRIBUTE) ); +    Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) ); +    Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) ); +    assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) ); +    return iPos; +} +int Rtl_NtkReadAttribute2( Rtl_Lib_t * p, int iPos ) +{ +//char * pTok1 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos-1)); +//char * pTok2 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos)  ); +//char * pTok3 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos+1)); +    assert( Vec_IntEntry(p->vTokens, iPos-1) == p->pMap[RTL_ATTRIBUTE] ); +    Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) ); +    Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) ); +    assert( Vec_IntEntry(p->vTokens, iPos) == p->pMap[RTL_NONE] ); +    return iPos; +} +int Rtl_NtkReadConnect( Rtl_Ntk_t * p, int iPos ) +{ +//char * pTok1 = Rtl_NtkTokStr(p, iPos-1); +//char * pTok2 = Rtl_NtkTokStr(p, iPos); +//char * pTok3 = Rtl_NtkTokStr(p, iPos+1); +    assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CONNECT) ); +    Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) ); +    Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) ); +    assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) ); +    return iPos; +} +int Rtl_NtkReadCell( Rtl_Ntk_t * p, int iPos ) +{ +    Vec_Int_t * vAttrs = &p->pLib->vAttrTemp; +    int iPosPars, iPosCons, Par, Val, i, Entry; +    assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CELL) ); +    Vec_IntPush( &p->vCells, Vec_IntSize(&p->vStore) ); +    Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 0 +    Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 1 +    Vec_IntPush( &p->vStore, -1 ); +    Vec_IntPush( &p->vStore, -1 ); +    assert( Vec_IntSize(vAttrs) % 2 == 0 ); +    Vec_IntPush( &p->vStore, Vec_IntSize(vAttrs)/2 ); +    iPosPars = Vec_IntSize(&p->vStore); +    Vec_IntPush( &p->vStore, 0 );  // 5 +    iPosCons = Vec_IntSize(&p->vStore); +    Vec_IntPush( &p->vStore, 0 );  // 6 +    Vec_IntPush( &p->vStore, 0 );  // 7 +    assert( Vec_IntSize(&p->vStore) == Vec_IntEntryLast(&p->vCells)+CELL_NUM ); +    Vec_IntAppend( &p->vStore, vAttrs ); +    Vec_IntClear( vAttrs ); +    Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos ) +    { +        if ( Rtl_NtkTokCheck(p, Entry, RTL_END) ) +            break; +        if ( Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) || Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) ) +        { +            int iPosCount = Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) ? iPosPars : iPosCons; +            Vec_IntAddToEntry( &p->vStore, iPosCount, 1 ); +            i++; +            Par = Rtl_NtkReadSig(p, &i); +            Val = Rtl_NtkReadSig(p, &i);             +            Vec_IntPushTwo( &p->vStore, Par, Val ); +        } +        assert( Rtl_NtkPosCheck(p, i, RTL_NONE) ); +    } +    assert( Rtl_NtkPosCheck(p, i, RTL_END) ); +    i++; +    assert( Rtl_NtkPosCheck(p, i, RTL_NONE) ); +    return i; +} +int Wln_ReadMatchEnd( Rtl_Ntk_t * p, int Mod ) +{ +    int i, Entry, Count = 0; +    Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, Mod ) +        if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) ) +            Count++; +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_END) ) +        { +            if ( Count == 0 ) +                return i; +            Count--; +        } +    assert( 0 ); +    return -1; +} +int Rtl_NtkReadNtk( Rtl_Lib_t * pLib, int Mod ) +{ +    Rtl_Ntk_t * p = Rtl_NtkAlloc( pLib ); +    Vec_Int_t * vAttrs = &p->pLib->vAttrTemp; +    int End = Wln_ReadMatchEnd( p, Mod ), i, Entry; +    assert( Rtl_NtkPosCheck(p, Mod-1, RTL_MODULE) ); +    assert( Rtl_NtkPosCheck(p, End, RTL_END)    ); +    p->NameId = Rtl_NtkTokId( p, Mod ); +    p->Slice0 = Vec_IntSize( &pLib->vSlices ); +    Vec_IntAppend( &p->vAttrs, vAttrs ); +    Vec_IntClear( vAttrs ); +    Vec_IntForEachEntryStartStop( pLib->vTokens, Entry, i, Mod, End ) +    { +        if ( Rtl_NtkTokCheck(p, Entry, RTL_WIRE) ) +            i = Rtl_NtkReadWire( p, i+1 ); +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_ATTRIBUTE) ) +            i = Rtl_NtkReadAttribute( p, i+1 ); +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) ) +            i = Rtl_NtkReadCell( p, i+1 ); +        else if ( Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) ) +            i = Rtl_NtkReadConnect( p, i+1 ); +    } +    p->Slice1 = Vec_IntSize( &pLib->vSlices ); +    assert( Vec_IntSize(&p->vWires) % WIRE_NUM == 0 ); +    return End; +} +void Rtl_NtkReportUndefs( Rtl_Ntk_t * p ) +{ +    Vec_Int_t * vNames, * vCounts; +    int i, iName, * pCell, nUndef = 0; +    vNames  = Vec_IntAlloc( 10 ); +    vCounts = Vec_IntAlloc( 10 ); +    Rtl_NtkForEachCell( p, pCell, i ) +        if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 )  +        { +            iName = Vec_IntFind(vNames, Rtl_CellType(pCell)); +            if ( iName == -1 ) +            { +                iName = Vec_IntSize(vNames); +                Vec_IntPush( vNames, Rtl_CellType(pCell) ); +                Vec_IntPush( vCounts, 0 ); +            } +            Vec_IntAddToEntry( vCounts, iName, 1 ); +        } +    Vec_IntForEachEntry( vNames, iName, i ) +        printf( "  %s (%d)", Rtl_NtkStr(p, iName), Vec_IntEntry(vCounts, i) ); +    printf( "\n" ); +    Vec_IntFree( vNames ); +    Vec_IntFree( vCounts ); +} +int Rtl_NtkSetParents( Rtl_Ntk_t * p ) +{ +    int i, * pCell, nUndef = 0; +    Rtl_NtkForEachCell( p, pCell, i ) +    { +        pCell[2] = Rtl_NtkReadType( p, Rtl_CellType(pCell) ); +        if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 )  +            nUndef++; +        else +            pCell[3] = Rtl_CellModule(pCell) < ABC_INFINITY ? pCell[6]-1 : Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY)->nInputs; +    } +    if ( !nUndef ) +        return 0; +    printf( "Module \"%s\" has %d blackbox instances: ", Rtl_NtkName(p), nUndef ); +    Rtl_NtkReportUndefs( p ); +    return nUndef; +} +void Rtl_LibSetParents( Rtl_Lib_t * p ) +{ +    Rtl_Ntk_t * pNtk; int i; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        Rtl_NtkSetParents( pNtk );   +} +void Rtl_LibReorderModules_rec( Rtl_Ntk_t * p, Vec_Ptr_t * vNew ) +{ +    int i, * pCell; +    Rtl_NtkForEachCell( p, pCell, i ) +    { +        Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell ); +        if ( pMod && pMod->iCopy == -1 ) +            Rtl_LibReorderModules_rec( pMod, vNew ); +    } +    assert( p->iCopy == -1 ); +    p->iCopy = Vec_PtrSize(vNew); +    Vec_PtrPush( vNew, p ); +} +void Rtl_NtkUpdateBoxes( Rtl_Ntk_t * p ) +{ +    int i, * pCell; +    Rtl_NtkForEachCell( p, pCell, i ) +    { +        Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell ); +        if ( pMod )  +            pCell[2] = ABC_INFINITY + pMod->iCopy; +    } +} +void Rtl_LibUpdateBoxes( Rtl_Lib_t * p ) +{ +    Rtl_Ntk_t * pNtk; int i; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        Rtl_NtkUpdateBoxes( pNtk );   +} +void Rtl_LibReorderModules( Rtl_Lib_t * p ) +{ +    Vec_Ptr_t * vNew = Vec_PtrAlloc( Vec_PtrSize(p->vNtks) ); +    Rtl_Ntk_t * pNtk; int i; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        pNtk->iCopy = -1; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) +        if ( pNtk->iCopy == -1 ) +            Rtl_LibReorderModules_rec( pNtk, vNew ); +    assert( Vec_PtrSize(p->vNtks) == Vec_PtrSize(vNew) ); +    Rtl_LibUpdateBoxes( p ); +    Vec_PtrClear( p->vNtks ); +    Vec_PtrAppend( p->vNtks, vNew ); +    Vec_PtrFree( vNew ); +} +Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec ) +{ +    Rtl_Lib_t * p = Rtl_LibAlloc(); int i, Entry; +    p->pSpec      = Abc_UtilStrsav( pFileSpec ); +    p->pManName   = Abc_NamStart( 1000, 50 ); +    p->vTokens    = Rtl_NtkReadFile( pFileName, p->pManName ); +    Rtl_LibDeriveMap( p ); +    Vec_IntClear( &p->vAttrTemp ); +    Vec_IntForEachEntry( p->vTokens, Entry, i ) +        if ( Entry == p->pMap[RTL_MODULE] ) +            i = Rtl_NtkReadNtk( p, i+1 ); +        else if ( Entry == p->pMap[RTL_ATTRIBUTE] ) +            i = Rtl_NtkReadAttribute2( p, i+1 ); +    Rtl_LibSetParents( p ); +    Rtl_LibReorderModules( p ); +    return p; +} + + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +extern void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig ); + +void Rtl_NtkCollectWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right ) +{ +    int Wire  = Rtl_WireMapNameToId( p, NameId ); +    int First = Rtl_WireBitStart( p, Wire ); +    int Width = Rtl_WireWidth( p, Wire ), i; +    Left  = Left  == -1 ? Width-1 :  Left; +    Right = Right == -1 ? 0       : Right; +    assert ( Right >= 0 && Right <= Left ); +    for ( i = Right; i <= Left; i++ ) +    { +        assert( Vec_IntEntry(&p->vLits, First+i) != -1 ); +        Vec_IntPush( &p->vBitTemp, Vec_IntEntry(&p->vLits, First+i) ); +    } +} +void Rtl_NtkCollectConstRange( Rtl_Ntk_t * p, int * pConst ) +{ +    int i, nLimit = pConst[0]; +    if ( nLimit == -1 ) +        nLimit = 32; +    //assert( pConst[0] > 0 ); +    for ( i = 0; i < nLimit; i++ ) +        Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit(pConst+1,i) ); +} +void Rtl_NtkCollectSliceRange( Rtl_Ntk_t * p, int * pSlice ) +{ +    Rtl_NtkCollectWireRange( p, pSlice[0], pSlice[1], pSlice[2] ); +} +void Rtl_NtkCollectConcatRange( Rtl_Ntk_t * p, int * pConcat ) +{ +    int i; +    for ( i = pConcat[0]; i >= 1; i-- ) +        Rtl_NtkCollectSignalRange( p, pConcat[i] ); +} +void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig ) +{ +    if ( Rtl_SigIsNone(Sig) ) +        Rtl_NtkCollectWireRange( p, Sig >> 2, -1, -1 ); +    else if ( Rtl_SigIsConst(Sig) ) +        Rtl_NtkCollectConstRange( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) ); +    else if ( Rtl_SigIsSlice(Sig) ) +        Rtl_NtkCollectSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); +    else if ( Rtl_SigIsConcat(Sig) ) +        Rtl_NtkCollectConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); +    else assert( 0 ); +} + + +extern int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits ); + +int Rtl_NtkInsertWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int * pLits, int nLits ) +{ +    //char * pName = Rtl_NtkStr( p, NameId ); +    int Wire  = Rtl_WireMapNameToId( p, NameId ); +    int First = Rtl_WireBitStart( p, Wire ); +    int Width = Rtl_WireWidth( p, Wire ), i, k = 0; +    Left  = Left  == -1 ? Width-1 :  Left; +    Right = Right == -1 ? 0       : Right; +    assert ( Right >= 0 && Right <= Left ); +    for ( i = Right; i <= Left; i++ ) +    { +        assert( Vec_IntEntry(&p->vLits, First+i) == -1 ); +        Vec_IntWriteEntry(&p->vLits, First+i, pLits[k++] ); +    } +    assert( k <= nLits ); +    return k; +} +int Rtl_NtkInsertSliceRange( Rtl_Ntk_t * p, int * pSlice, int * pLits, int nLits ) +{ +    return Rtl_NtkInsertWireRange( p, pSlice[0], pSlice[1], pSlice[2], pLits, nLits ); +} +int Rtl_NtkInsertConcatRange( Rtl_Ntk_t * p, int * pConcat, int * pLits, int nLits ) +{ +    int i, k = 0; +    for ( i = 1; i <= pConcat[0]; i++ ) +        k += Rtl_NtkInsertSignalRange( p, pConcat[i], pLits+k, nLits-k ); +    assert( k <= nLits ); +    return k; +} +int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits ) +{ +    int nBits = ABC_INFINITY; +    if ( Rtl_SigIsNone(Sig) ) +        nBits = Rtl_NtkInsertWireRange( p, Sig >> 2, -1, -1, pLits, nLits ); +    if ( Rtl_SigIsSlice(Sig) ) +        nBits = Rtl_NtkInsertSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), pLits, nLits ); +    if ( Rtl_SigIsConcat(Sig) ) +        nBits = Rtl_NtkInsertConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), pLits, nLits ); +    if ( Rtl_SigIsConst(Sig) ) +        assert( 0 ); +    assert( nBits == nLits ); +    return nBits; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rtl_NtkBlastInputs( Gia_Man_t * pNew, Rtl_Ntk_t * p ) +{ +    int b, i; +    for ( i = 0; i < p->nInputs; i++ ) +    { +        int First = Rtl_WireBitStart( p, i ); +        int Width = Rtl_WireWidth( p, i ); +        for ( b = 0; b < Width; b++ ) +        { +            assert( Vec_IntEntry(&p->vLits, First+b) == -1 ); +            Vec_IntWriteEntry( &p->vLits, First+b, Gia_ManAppendCi(pNew) ); +        } +    } +} +void Rtl_NtkBlastOutputs( Gia_Man_t * pNew, Rtl_Ntk_t * p ) +{ +    int b, i; +    for ( i = 0; i < p->nOutputs; i++ ) +    { +        int First = Rtl_WireBitStart( p, p->nInputs + i ); +        int Width = Rtl_WireWidth( p, p->nInputs + i ); +        for ( b = 0; b < Width; b++ ) +        { +            assert( Vec_IntEntry(&p->vLits, First+b) != -1 ); +            Gia_ManAppendCo( pNew, Vec_IntEntry(&p->vLits, First+b) ); +        } +    } +} +void Rtl_NtkBlastConnect( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCon ) +{ +    int nBits; +    Vec_IntClear( &p->vBitTemp ); +    Rtl_NtkCollectSignalRange( p, pCon[0] ); +    nBits = Rtl_NtkInsertSignalRange( p, pCon[1], Vec_IntArray(&p->vBitTemp), Vec_IntSize(&p->vBitTemp) ); +    assert( nBits == Vec_IntSize(&p->vBitTemp) ); +    //printf( "Finished blasting connection (Value = %d).\n", Vec_IntEntry(&p->vBitTemp, 0) ); +} +void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) +{ +    extern Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ); +    extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ); +    Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); +    int k, Par, Val, nBits = 0; +    Vec_IntClear( &p->vBitTemp ); +    Rtl_CellForEachInput( p, pCell, Par, Val, k ) +        Rtl_NtkCollectSignalRange( p, Val ); +//    if ( pModel->pGia == NULL ) +//        pModel->pGia = Rtl_NtkBlast( pModel ); +    assert( pModel->pGia ); +    Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp ); +    Rtl_CellForEachOutput( p, pCell, Par, Val, k ) +        nBits += Rtl_NtkInsertSignalRange( p, Val, Vec_IntArray(&p->vBitTemp)+nBits, Vec_IntSize(&p->vBitTemp)-nBits ); +    assert( nBits == Vec_IntSize(&p->vBitTemp) ); +} + +int Rtl_NtkCellParamValue( Rtl_Ntk_t * p, int * pCell, char * pParam ) +{ +    int ParamId = Rtl_NtkStrId( p, pParam ); +    int i, Par, Val, ValOut = ABC_INFINITY, * pConst; +//    p->pLib->pFile = stdout; +//    Rtl_CellForEachParam( p, pCell, Par, Val, i ) +//        fprintf( Rtl_NtkFile(p), "    parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" ); +    Rtl_CellForEachParam( p, pCell, Par, Val, i ) +        if ( (Par >> 2) == ParamId ) +        { +            assert( Rtl_SigIsConst(Val) ); +            pConst = Vec_IntEntryP( &p->pLib->vConsts, Val >> 2 ); +            assert( pConst[0] < 32 ); +            ValOut = pConst[1]; +        } +    return ValOut; +} +void Rtl_NtkBlastOperator( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) +{ +    extern void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 ); +    Vec_Int_t * vRes = &p->pLib->vTemp[3]; +    int i, Par, Val, ValOut = -1, nBits = 0, nRange = -1; +    int fSign0 = Rtl_NtkCellParamValue( p, pCell, "\\A_SIGNED" ); +    int fSign1 = Rtl_NtkCellParamValue( p, pCell, "\\B_SIGNED" ); +    Rtl_CellForEachOutput( p, pCell, Par, ValOut, i ) +        nRange = Rtl_NtkCountSignalRange( p, ValOut ); +    assert( nRange > 0 ); +    for ( i = 0; i < TEMP_NUM; i++ ) +        Vec_IntClear( &p->pLib->vTemp[i] ); +    //printf( "Starting blasting cell %s.\n", Rtl_CellNameStr(p, pCell) ); +    Rtl_CellForEachInput( p, pCell, Par, Val, i ) +    { +        Vec_IntClear( &p->vBitTemp ); +        Rtl_NtkCollectSignalRange( p, Val ); +        Vec_IntAppend( &p->pLib->vTemp[i], &p->vBitTemp ); +    } +    Rtl_NtkBlastNode( pNew, Rtl_CellModule(pCell), Rtl_CellInputNum(pCell), p->pLib->vTemp, nRange, fSign0, fSign1 ); +    assert( Vec_IntSize(vRes) > 0 ); +    nBits = Rtl_NtkInsertSignalRange( p, ValOut, Vec_IntArray(vRes)+nBits, Vec_IntSize(vRes)-nBits ); +    assert( nBits == Vec_IntSize(vRes) ); +    //printf( "Finished blasting cell %s (Value = %d).\n", Rtl_CellNameStr(p, pCell), Vec_IntEntry(vRes, 0) ); +} +Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) +{ +    Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); +    int i, iObj, * pCell, nBits = Rtl_NtkRangeWires( p ); +    char Buffer[100]; static int counter = 0; +    Vec_IntFill( &p->vLits, nBits, -1 ); +    Rtl_NtkMapWires( p, 0 ); +    Rtl_NtkBlastInputs( pNew, p ); +    Gia_ManHashAlloc( pNew ); +    Vec_IntForEachEntry( &p->vOrder, iObj, i ) +    { +        iObj -= Rtl_NtkInputNum(p); +        if ( iObj < 0 ) +            continue; +        if ( iObj >= Rtl_NtkCellNum(p) ) +        { +            Rtl_NtkBlastConnect( pNew, p, Rtl_NtkCon(p, iObj - Rtl_NtkCellNum(p)) ); +            continue; +        } +        pCell = Rtl_NtkCell(p, iObj); +        if ( Rtl_CellModule(pCell) >= ABC_INFINITY ) +            Rtl_NtkBlastHierarchy( pNew, p, pCell ); +        else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST ) +            Rtl_NtkBlastOperator( pNew, p, pCell ); +        else +            printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) ); +    } +    Gia_ManHashStop( pNew ); +    Rtl_NtkBlastOutputs( pNew, p ); +    Rtl_NtkMapWires( p, 1 ); +    pNew = Gia_ManCleanup( pTemp = pNew ); +    Gia_ManStop( pTemp ); + +sprintf( Buffer, "temp%d.aig", counter++ ); +//sprintf( Buffer, "temp%d.aig", counter ); +Gia_AigerWrite( pNew, Buffer, 0, 0, 0 ); +printf( "Dumpted blasted AIG into file \"%s\" for module \"%s\".\n", Buffer, Rtl_NtkName(p) ); +Gia_ManPrintStats( pNew, NULL ); +    return pNew; +} +void Rtl_LibBlast( Rtl_Lib_t * pLib ) +{ +    Rtl_Ntk_t * p; int i; +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) +        if ( p->pGia == NULL ) +            p->pGia = Rtl_NtkBlast( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rtl_LibPreprocess( Rtl_Lib_t * pLib ) +{ +    abctime clk = Abc_Clock();  +    Rtl_Ntk_t * p1, * p2, * p; +    int i, k, Status, fFound = 0; +    printf( "Performing preprocessing for verification.\n" ); +    // find similar modules +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p1, i ) +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p2, k ) +    { +        if ( i >= k )   +            continue; +        if ( Gia_ManCiNum(p1->pGia) != Gia_ManCiNum(p2->pGia) ||  +             Gia_ManCoNum(p1->pGia) != Gia_ManCoNum(p2->pGia) ) +            continue; +        // two similar modules +        Status = Cec_ManVerifyTwo( p1->pGia, p2->pGia, 0 ); +        if ( Status != 1 ) +            continue; +        printf( "Proved equivalent modules: %s == %s\n", Rtl_NtkName(p1), Rtl_NtkName(p2) ); +        // inline +        if ( Gia_ManAndNum(p1->pGia) > Gia_ManAndNum(p2->pGia) ) +            ABC_SWAP( Gia_Man_t *, p1->pGia, p2->pGia ); +        assert( Gia_ManAndNum(p1->pGia) <= Gia_ManAndNum(p2->pGia) ); +        Gia_ManStopP( &p2->pGia ); +        p2->pGia = Gia_ManDup( p1->pGia ); +        fFound = 1; +        goto finish; +    } +finish: +    if ( fFound == 0 ) +        printf( "Preprocessing not succeded.\n" ); +    Abc_PrintTime( 1, "Preprocessing time", Abc_Clock() - clk ); +    // blast AIGs again +    Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) +        if ( p != p1 && p != p2 ) +            Gia_ManStopP( &p->pGia ); +    Rtl_LibBlast( pLib ); +} +void Rtl_LibSolve( Rtl_Lib_t * pLib ) +{ +    abctime clk = Abc_Clock(); int Status; +    Rtl_Ntk_t * pTop = Rtl_LibTop( pLib ); +    Gia_Man_t * pCopy = Gia_ManDup( pTop->pGia ); +    Gia_ManInvertPos( pCopy ); +    Gia_ManAppendCo( pCopy, 0 ); +    Status = Cec_ManVerifySimple( pCopy ); +    Gia_ManStop( pCopy ); +    if ( Status == 1 ) +        printf( "Verification problem solved!  " ); +    else +        printf( "Verification problem is NOT solved!  " ); +    Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index aff88af9..89680bbd 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -37,21 +37,6 @@ ABC_NAMESPACE_IMPL_START  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         ///  //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Wln_Ntk_t * Wln_ReadRtl( char * pFileName ) -{ -    return NULL; -}  /**Function************************************************************* @@ -96,28 +81,31 @@ int Wln_ConvertToRtl( char * pCommand, char * pFileTemp )      fclose( pFile );      return 1;  } -Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ) +Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose )  { -    Wln_Ntk_t * pNtk = NULL; +    Rtl_Lib_t * pNtk = NULL;      char Command[1000];      char * pFileTemp = "_temp_.rtlil";      int fSVlog = strstr(pFileName, ".sv") != NULL; -    sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; write_rtlil %s\"",  +    if ( strstr(pFileName, ".rtl") ) +        return Rtl_LibReadFile( pFileName, pFileName ); +    sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; %sproc; write_rtlil %s\"",           Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName,  -        pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", pFileTemp ); +        pTopModule ? "-top " : "-auto-top",  +        pTopModule ? pTopModule : "",  +        fCollapse ? "flatten; " : "", +        pFileTemp );      if ( fVerbose )      printf( "%s\n", Command );      if ( !Wln_ConvertToRtl(Command, pFileTemp) ) -    {          return NULL; -    } -    pNtk = Wln_ReadRtl( pFileTemp ); +    pNtk = Rtl_LibReadFile( pFileTemp, pFileName );      if ( pNtk == NULL )      {          printf( "Dumped the design into file \"%s\".\n", pFileTemp );          return NULL;      } -    unlink( pFileTemp ); +    //unlink( pFileTemp );      return pNtk;  }  Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ) @@ -125,10 +113,16 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSk      Gia_Man_t * pGia = NULL;      char Command[1000];      char * pFileTemp = "_temp_.aig"; -    int fSVlog = strstr(pFileName, ".sv") != NULL; -    sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"",  -        Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName,  -        pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", fTechMap ? "techmap; setundef -zero; " : "", pFileTemp ); +    int fRtlil = strstr(pFileName, ".rtl") != NULL; +    int fSVlog = strstr(pFileName, ".sv")  != NULL; +    sprintf( Command, "%s -qp \"%s%s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"",  +        Wln_GetYosysName(),  +        fRtlil ? "read_rtlil" : "read_verilog", +        fSVlog ? " -sv ":" ",  +        pFileName,  +        pTopModule ? "-top " : "-auto-top",  +        pTopModule ? pTopModule : "",  +        fTechMap ? "techmap; setundef -zero; " : "", pFileTemp );      if ( fVerbose )      printf( "%s\n", Command );      if ( !Wln_ConvertToRtl(Command, pFileTemp) ) | 
