diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/base/wlc/wlcBlast.c | 64 | ||||
| -rw-r--r-- | src/base/wlc/wlcReadVer.c | 97 | ||||
| -rw-r--r-- | src/base/wlc/wlcWriteVer.c | 24 | 
3 files changed, 167 insertions, 18 deletions
diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 3b4f5a17..418c2fa6 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -80,6 +80,15 @@ int Wlc_BlastGetConst( int * pNum, int nNum )              return -1;      return Res;  } +int Wlc_NtkMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift ) +{ +    int iLit0, iLit1; +    if ( nCtrl == 0 ) +        return Vec_IntEntry( vData, Shift ); +    iLit0 = Wlc_NtkMuxTree_rec( pNew, pCtrl, nCtrl-1, vData, Shift ); +    iLit1 = Wlc_NtkMuxTree_rec( pNew, pCtrl, nCtrl-1, vData, Shift + (1<<(nCtrl-1)) ); +    return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 ); +}  /**Function************************************************************* @@ -333,7 +342,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )      Vec_Int_t * vBits, * vTemp0, * vTemp1, * vTemp2, * vRes;      int nBits = Wlc_NtkPrepareBits( p );      int nRange, nRange0, nRange1, nRange2; -    int i, k, b, iLit, * pFans0, * pFans1, * pFans2; +    int i, k, b, iFanin, iLit, * pFans0, * pFans1, * pFans2;      vBits  = Vec_IntAlloc( nBits );      vTemp0 = Vec_IntAlloc( 1000 );      vTemp1 = Vec_IntAlloc( 1000 ); @@ -346,7 +355,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )      // create primary inputs      Wlc_NtkForEachObj( p, pObj, i )      { -//        char * pName = Wlc_ObjName(p, i); +        char * pName = Wlc_ObjName(p, i);          nRange  = Wlc_ObjRange( pObj );          nRange0 = Wlc_ObjFaninNum(pObj) > 0 ? Wlc_ObjRange( Wlc_ObjFanin0(p, pObj) ) : -1;          nRange1 = Wlc_ObjFaninNum(pObj) > 1 ? Wlc_ObjRange( Wlc_ObjFanin1(p, pObj) ) : -1; @@ -362,9 +371,18 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )          }          else if ( pObj->Type == WLC_OBJ_PO || pObj->Type == WLC_OBJ_BUF )          { -//            assert( nRange <= nRange0 ); -            for ( k = 0; k < nRange; k++ ) -                Vec_IntPush( vRes, k < nRange0 ? pFans0[k] : 0 ); +            if ( pObj->Type == WLC_OBJ_BUF && pObj->Signed && !Wlc_ObjFanin0(p, pObj)->Signed ) // unsign->sign +            { +                int nRangeMax = Abc_MaxInt( nRange0, nRange ); +                int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, 0 ); +                Wlc_BlastMinus( pNew, pArg0, nRange, vRes ); +            } +            else +            { +    //            assert( nRange <= nRange0 ); +                for ( k = 0; k < nRange; k++ ) +                    Vec_IntPush( vRes, k < nRange0 ? pFans0[k] : 0 ); +            }          }          else if ( pObj->Type == WLC_OBJ_CONST )          { @@ -374,9 +392,19 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )          }          else if ( pObj->Type == WLC_OBJ_MUX )          { -            assert( nRange0 == 1 && nRange1 == nRange && nRange2 == nRange ); -            for ( k = 0; k < nRange; k++ ) -                Vec_IntPush( vRes, Gia_ManHashMux(pNew, pFans0[0], pFans1[k], pFans2[k]) ); +            assert( 1 + (1 << nRange0) == Wlc_ObjFaninNum(pObj) ); +            for ( b = 0; b < nRange; b++ ) +            { +                Vec_IntClear( vTemp0 ); +                Wlc_ObjForEachFanin( pObj, iFanin, k ) +                { +                    if ( !k ) continue; +                    assert( nRange == Wlc_ObjRange(Wlc_NtkObj(p, iFanin)) ); +                    pFans1 = Vec_IntEntryP( vBits, Wlc_ObjCopy(p, iFanin) ); +                    Vec_IntPush( vTemp0, pFans1[b] ); +                } +                Vec_IntPush( vRes, Wlc_NtkMuxTree_rec(pNew, pFans0, nRange0, vTemp0, 0) ); +            }          }          else if ( pObj->Type == WLC_OBJ_SHIFT_R || pObj->Type == WLC_OBJ_SHIFT_RA )          { @@ -487,12 +515,14 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )          else if ( pObj->Type == WLC_OBJ_COMP_LESS || pObj->Type == WLC_OBJ_COMP_MOREEQU ||                    pObj->Type == WLC_OBJ_COMP_MORE || pObj->Type == WLC_OBJ_COMP_LESSEQU )          { +            int nRangeMax = Abc_MaxInt( nRange0, nRange1 ); +            int * pArg0 = Wlc_VecLoadFanins( vRes,   pFans0, nRange0, nRangeMax, Wlc_ObjFanin0(p, pObj)->Signed ); +            int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjFanin1(p, pObj)->Signed );              int fSwap  = (pObj->Type == WLC_OBJ_COMP_MORE    || pObj->Type == WLC_OBJ_COMP_LESSEQU);              int fCompl = (pObj->Type == WLC_OBJ_COMP_MOREEQU || pObj->Type == WLC_OBJ_COMP_LESSEQU);              assert( nRange == 1 ); -            assert( nRange0 == nRange1 );              if ( fSwap ) ABC_SWAP( int *, pFans0, pFans1 ); -            iLit = Wlc_BlastLess( pNew, pFans0, pFans1, nRange0 ); +            iLit = Wlc_BlastLess( pNew, pFans0, pFans1, nRangeMax );              iLit = Abc_LitNotCond( iLit, fCompl );              Vec_IntFill( vRes, 1, iLit );          } @@ -516,15 +546,17 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p )          }          else if ( pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_MODULUS )          { -            int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange, Wlc_ObjFanin0(p, pObj)->Signed ); -            int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRange, Wlc_ObjFanin1(p, pObj)->Signed ); -            assert( nRange0 <= nRange && nRange1 <= nRange ); -            Wlc_BlastDivider( pNew, pArg0, nRange, pArg1, nRange, pObj->Type == WLC_OBJ_ARI_DIVIDE, vRes ); +            int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(nRange0, nRange1) ); +            int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRangeMax, Wlc_ObjFanin0(p, pObj)->Signed ); +            int * pArg1 = Wlc_VecLoadFanins( vTemp1, pFans1, nRange1, nRangeMax, Wlc_ObjFanin1(p, pObj)->Signed ); +            Wlc_BlastDivider( pNew, pArg0, nRangeMax, pArg1, nRangeMax, pObj->Type == WLC_OBJ_ARI_DIVIDE, vRes ); +            Vec_IntShrink( vRes, nRange );          }          else if ( pObj->Type == WLC_OBJ_ARI_MINUS )          { -            assert( nRange0 == nRange ); -            Wlc_BlastMinus( pNew, pFans0, nRange0, vRes ); +            int * pArg0 = Wlc_VecLoadFanins( vTemp0, pFans0, nRange0, nRange, Wlc_ObjFanin0(p, pObj)->Signed ); +            assert( nRange0 <= nRange ); +            Wlc_BlastMinus( pNew, pArg0, nRange, vRes );          }          else if ( pObj->Type == WLC_OBJ_TABLE )              Wlc_BlastTable( pNew, Wlc_ObjTable(p, pObj), pFans0, nRange0, nRange, vRes ); diff --git a/src/base/wlc/wlcReadVer.c b/src/base/wlc/wlcReadVer.c index 32375ac0..78af2d42 100644 --- a/src/base/wlc/wlcReadVer.c +++ b/src/base/wlc/wlcReadVer.c @@ -398,7 +398,7 @@ static inline char * Wlc_PrsFindName( char * pStr, char ** ppPlace )  }  static inline char * Wlc_PrsReadConstant( Wlc_Prs_t * p, char * pStr, Vec_Int_t * vFanins, int * pRange, int * pSigned )  { -    int nDigits, nBits = atoi( pStr ); +    int i, nDigits, nBits = atoi( pStr );      *pRange = -1;      *pSigned = 0;      pStr = Wlc_PrsSkipSpaces( pStr ); @@ -418,6 +418,18 @@ static inline char * Wlc_PrsReadConstant( Wlc_Prs_t * p, char * pStr, Vec_Int_t          *pSigned = 1;          pStr++;      } +    if ( pStr[1] == 'b' ) +    { +        Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); +        for ( i = 0; i < nBits; i++ ) +            if ( pStr[2+i] == '1' ) +                Abc_InfoSetBit( (unsigned *)Vec_IntArray(vFanins), i ); +            else if ( pStr[2+i] != '0' ) +                return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Wrong digit in binary constant \"%c\".", pStr[2+i] ); +        *pRange = nBits; +        pStr += 2 + nBits; +        return pStr; +    }      if ( pStr[1] != 'h' )          return (char *)(ABC_PTRINT_T)Wlc_PrsWriteErrorMessage( p, pStr, "Expecting hexadecimal constant and not \"%c\".", pStr[1] );      Vec_IntFill( vFanins, Abc_BitWordNum(nBits), 0 ); @@ -652,6 +664,8 @@ int Wlc_PrsReadDeclaration( Wlc_Prs_t * p, char * pStart )      pStart = Wlc_PrsSkipSpaces( pStart );      if ( Wlc_PrsStrCmp( pStart, "wire" ) )          pStart += strlen("wire"); +    else if ( Wlc_PrsStrCmp( pStart, "reg" ) ) +        pStart += strlen("reg");      // read 'signed'      pStart = Wlc_PrsFindWord( pStart, "signed", &Signed );      // read range @@ -696,6 +710,7 @@ int Wlc_PrsDerive( Wlc_Prs_t * p )      // go through the directives      Wlc_PrsForEachLine( p, pStart, i )      { +startword:          if ( Wlc_PrsStrCmp( pStart, "module" ) )          {              // get module name @@ -770,7 +785,7 @@ int Wlc_PrsDerive( Wlc_Prs_t * p )              break;          }          // these are read as part of the interface -        else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) ) +        else if ( Wlc_PrsStrCmp( pStart, "input" ) || Wlc_PrsStrCmp( pStart, "output" ) || Wlc_PrsStrCmp( pStart, "wire" ) || Wlc_PrsStrCmp( pStart, "reg" ) )          {              if ( !Wlc_PrsReadDeclaration( p, pStart ) )                  return 0; @@ -833,6 +848,84 @@ int Wlc_PrsDerive( Wlc_Prs_t * p )                  Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins );              }          } +        else if ( Wlc_PrsStrCmp( pStart, "always" ) ) +        { +            // THIS IS A HACK TO DETECT tables +            int NameId, NameIdOut = -1, fFound; +            // find control +            pStart = Wlc_PrsFindWord( pStart, "case", &fFound ); +            if ( pStart == NULL ) +                return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read case statement." ); +            // read the name +            pStart = Wlc_PrsFindSymbol( pStart, '(' ); +            if ( pStart == NULL ) +                return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." ); +            pStart = Wlc_PrsFindSymbol( pStart+1, '(' ); +            if ( pStart == NULL ) +                return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read table." ); +            pStart = Wlc_PrsFindName( pStart+1, &pName ); +            if ( pStart == NULL ) +                return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after case." ); +            NameId = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); +            if ( !fFound ) +                return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName ); +            Vec_IntClear( p->vFanins ); +            Vec_IntPush( p->vFanins, NameId ); +            // read data inputs +            while ( 1 ) +            { +                // find opening +                pStart = Wlc_PrsFindSymbol( pStart, ':' ); +                if ( pStart == NULL ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot find colon in the case statement." ); +                // find output name +                pStart = Wlc_PrsFindName( pStart+1, &pName ); +                if ( pStart == NULL ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name after case." ); +                NameIdOut = Abc_NamStrFindOrAdd( p->pNtk->pManName, pName, &fFound ); +                if ( !fFound ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Name %s is not declared.", pName ); +                // find equality +                pStart = Wlc_PrsFindSymbol( pStart, '=' ); +                if ( pStart == NULL ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot find equality in the case statement." ); +                // find input name +                pStart = Wlc_PrsSkipSpaces( pStart+1 ); +                pStart = Wlc_PrsReadName( p, pStart, p->vFanins ); +                if ( pStart == NULL ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read name inside case statement." ); +                // get next line and check its opening character +                pStart = Wlc_PrsStr(p, Vec_IntEntry(p->vStarts, ++i)); +                pStart = Wlc_PrsSkipSpaces( pStart ); +                if ( Wlc_PrsIsDigit(pStart) ) +                    continue; +                if ( Wlc_PrsStrCmp( pStart, "default" ) ) +                { +                    printf( "Ignoring default in Line %d.\n", i ); +                    pStart = Wlc_PrsStr(p, Vec_IntEntry(p->vStarts, ++i)); +                } +                // find closing +                pStart = Wlc_PrsFindWord( pStart, "endcase", &fFound ); +                if ( pStart == NULL ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read case statement." ); +                // find closing +                pStart = Wlc_PrsFindWord( pStart, "end", &fFound ); +                if ( pStart == NULL ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "Cannot read case statement." ); +                pStart = Wlc_PrsSkipSpaces( pStart ); +                break; +            } +            // check range of the control +            { +                Wlc_Obj_t * pObj = Wlc_NtkObj( p->pNtk, Vec_IntEntry(p->vFanins, 0) ); +                if ( (1 << Wlc_ObjRange(pObj)) != Vec_IntSize(p->vFanins) - 1 ) +                    return Wlc_PrsWriteErrorMessage( p, pStart, "The number of values in the case statement is wrong.", pName ); +                pObj = Wlc_NtkObj( p->pNtk, NameIdOut ); +                Wlc_ObjUpdateType( p->pNtk, pObj, WLC_OBJ_MUX ); +                Wlc_ObjAddFanins( p->pNtk, pObj, p->vFanins ); +                goto startword; +            } +        }  //        else if ( Wlc_PrsStrCmp( pStart, "CPL_FF" ) )          else          { diff --git a/src/base/wlc/wlcWriteVer.c b/src/base/wlc/wlcWriteVer.c index 262d5e52..6a615887 100644 --- a/src/base/wlc/wlcWriteVer.c +++ b/src/base/wlc/wlcWriteVer.c @@ -178,6 +178,30 @@ void Wlc_WriteVerInt( FILE * pFile, Wlc_Ntk_t * p )              else                  fprintf( pFile, "(%s << %d) | (%s >> %d)", pName0, Num0, pName0, Num1 );          } +        else if ( pObj->Type == WLC_OBJ_MUX && Wlc_ObjFaninNum(pObj) > 3 ) +        { +            fprintf( pFile, "       reg %s ;\n", pName ); +            fprintf( pFile, "       " ); +            fprintf( pFile, "always @( " ); +            Wlc_ObjForEachFanin( pObj, iFanin, k ) +                fprintf( pFile, "%s%s", k ? " or ":"", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) ); +            fprintf( pFile, " )\n" ); +            fprintf( pFile, "           " ); +            fprintf( pFile, "begin\n" ); +            fprintf( pFile, "             " ); +            fprintf( pFile, "case ( %s )\n", Wlc_ObjName(p, Wlc_ObjFaninId(pObj, 0)) ); +            Wlc_ObjForEachFanin( pObj, iFanin, k ) +            { +                if ( !k ) continue; +                fprintf( pFile, "               " ); +                fprintf( pFile, "%d : %s = %s ;\n", k-1, pName, Wlc_ObjName(p, Wlc_ObjFaninId(pObj, k)) ); +            } +            fprintf( pFile, "             " ); +            fprintf( pFile, "endcase\n" ); +            fprintf( pFile, "           " ); +            fprintf( pFile, "end\n" ); +            continue; +        }          else          {              fprintf( pFile, "       wire %s %-16s = ", Range, Wlc_ObjName(p, i) );  | 
