wlcAbc.c 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
/**CFile****************************************************************

  FileName    [wlcAbc.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Verilog parser.]

  Synopsis    [Parses several flavors of word-level Verilog.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - August 22, 2014.]

  Revision    [$Id: wlcAbc.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]

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

#include "wlc.h"
#include "base/abc/abc.h"

ABC_NAMESPACE_IMPL_START

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

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

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

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
void Wlc_NtkPrintInputInfo( Wlc_Ntk_t * pNtk )
{
    Wlc_Obj_t * pObj;
    int i, k, nRange, nBeg, nEnd, nBits = 0;
    FILE * output;

    output = fopen("abc_blast_input.info","w");

    Wlc_NtkForEachCi( pNtk, pObj, i )
    {
        nRange = Wlc_ObjRange(pObj);
        nBeg = pObj->Beg;
        nEnd = pObj->End;

        for ( k = 0; k < nRange; k++ )
        {
            int index = nEnd > nBeg ? nBeg + k : nEnd + k;
            char c = pObj->Type != WLC_OBJ_FO ? 'i' : pNtk->pInits[nBits + k];
            fprintf(output,"%s[%d] : %c \n", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), index , c );
        }
        if (pObj->Type == WLC_OBJ_FO)
            nBits += nRange;
    }

    Wlc_NtkForEachPo( pNtk, pObj, i )
    {
        nRange = Wlc_ObjRange(pObj);
        nBeg = pObj->Beg;
        nEnd = pObj->End;

        for ( k = 0; k < nRange; k++ )
        {
            int index = nEnd > nBeg ? nBeg + k : nEnd + k;
            fprintf(output,"%s[%d] : o \n", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), index);
        }
    }

    fclose(output);
    return;
}

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

  Synopsis    []

  Description []

  SideEffects []

  SeeAlso     []

***********************************************************************/
97
void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose )
98 99 100 101 102 103 104 105 106 107
{
    Wlc_Obj_t * pObj;
    int i, k, nNum, nRange, nBits = 0;
    Wlc_NtkForEachCi( pNtk, pObj, i )
    {
        if ( pObj->Type != WLC_OBJ_FO )
            continue;
        nRange = Wlc_ObjRange(pObj);
        for ( k = 0; k < nRange; k++ )
        {
108
            nNum = Vec_IntEntry(vCounts, nBits + k);
109 110 111 112 113 114 115 116 117 118 119
            if ( nNum )
                break;
        }
        if ( k == nRange )
        {
            nBits += nRange;
            continue;
        }
        printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
        for ( k = 0; k < nRange; k++ )
        {
120
            nNum = Vec_IntEntry( vCounts, nBits + k );
121 122 123 124 125 126 127
            if ( nNum == 0 )
                continue;
            printf( "  [%d] -> %d", k, nNum );
        }
        printf( "\n");
        nBits += nRange;
    }
128 129
    //printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
    assert( Vec_IntSize(vCounts) == nBits );
130 131 132 133 134 135 136 137 138 139 140 141 142
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
143
Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Ptr_t * vNamesIn )
144
{
145 146 147 148 149 150
    extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv );
    extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts );

    Vec_Int_t * vCounts = Pdr_InvCounts( vInv );
    Vec_Str_t * vSop = Pdr_InvPrintStr( vInv, vCounts );

151 152 153 154 155 156 157 158
    Wlc_Obj_t * pObj;
    int i, k, nNum, nRange, nBits = 0;
    Abc_Ntk_t * pMainNtk = NULL;
    Abc_Obj_t * pMainObj, * pMainTemp;
    char Buffer[5000];
    // start the network
    pMainNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
    // duplicate the name and the spec
159
    pMainNtk->pName = Extra_UtilStrsav(pNtk ? pNtk->pName : "inv");
160
    // create primary inputs
161
    if ( pNtk == NULL )
162
    {
163 164
        int Entry, nInputs = Abc_SopGetVarNum( Vec_StrArray(vSop) );
        Vec_IntForEachEntry( vCounts, Entry, i )
165
        {
166 167 168
            if ( Entry == 0 )
                continue;
            pMainObj = Abc_NtkCreatePi( pMainNtk );
169 170
            // If vNamesIn is given, take names from there for as many entries as possible
            // otherwise generate names from counter
171 172 173 174 175 176 177 178
            if (vNamesIn != NULL && i < Vec_PtrSize(vNamesIn)) {
                Abc_ObjAssignName( pMainObj, (char *)Vec_PtrEntry(vNamesIn, i), NULL );
            }
            else
            {
                sprintf( Buffer, "pi%d", i );
                Abc_ObjAssignName( pMainObj, Buffer, NULL );
            }
179
        }
180
        if ( Abc_NtkPiNum(pMainNtk) != nInputs )
181
        {
182 183 184
            printf( "Mismatch between number of inputs and the number of literals in the invariant.\n" );
            Abc_NtkDelete( pMainNtk );
            return NULL;
185
        }
186 187 188 189
    }
    else
    {
        Wlc_NtkForEachCi( pNtk, pObj, i )
190
        {
191
            if ( pObj->Type != WLC_OBJ_FO )
192
                continue;
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
            nRange = Wlc_ObjRange(pObj);
            for ( k = 0; k < nRange; k++ )
            {
                nNum = Vec_IntEntry(vCounts, nBits + k);
                if ( nNum )
                    break;
            }
            if ( k == nRange )
            {
                nBits += nRange;
                continue;
            }
            //printf( "%s[%d:%d] : ", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), pObj->End, pObj->Beg );
            for ( k = 0; k < nRange; k++ )
            {
                nNum = Vec_IntEntry( vCounts, nBits + k );
                if ( nNum == 0 )
                    continue;
                //printf( "  [%d] -> %d", k, nNum );
                pMainObj = Abc_NtkCreatePi( pMainNtk );
                sprintf( Buffer, "%s[%d]", Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k );
                Abc_ObjAssignName( pMainObj, Buffer, NULL );

            }
            //printf( "\n");
            nBits += nRange;
219 220
        }
    }
221 222
    //printf( "%d %d\n", Vec_IntSize(vCounts), nBits );
    assert( pNtk == NULL || Vec_IntSize(vCounts) == nBits );
223 224 225 226 227
    // create node
    pMainObj = Abc_NtkCreateNode( pMainNtk );
    Abc_NtkForEachPi( pMainNtk, pMainTemp, i )
        Abc_ObjAddFanin( pMainObj, pMainTemp );
    pMainObj->pData = Abc_SopRegister( (Mem_Flex_t *)pMainNtk->pManFunc, Vec_StrArray(vSop) );
228 229
    Vec_IntFree( vCounts );
    Vec_StrFree( vSop );
230 231 232 233 234 235 236
    // create PO
    pMainTemp = Abc_NtkCreatePo( pMainNtk );
    Abc_ObjAddFanin( pMainTemp, pMainObj );
    Abc_ObjAssignName( pMainTemp, "inv", NULL );
    return pMainNtk;
}

237 238
/**Function*************************************************************

239
  Synopsis    [Translate current network into an invariant.]
240 241 242 243 244 245 246 247

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
248
Vec_Int_t * Wlc_NtkGetPut( Abc_Ntk_t * pNtk, Gia_Man_t * pGia )
249
{
250
    int nRegs = Gia_ManRegNum(pGia);
251 252 253 254 255 256 257
    Vec_Int_t * vRes = NULL;
    if ( Abc_NtkPoNum(pNtk) != 1 )
        printf( "The number of outputs is other than 1.\n" );
    else if ( Abc_NtkNodeNum(pNtk) != 1 )
        printf( "The number of internal nodes is other than 1.\n" );
    else
    {
258 259
        Abc_Nam_t * pNames = NULL;
        Abc_Obj_t * pFanin, * pNode = Abc_ObjFanin0( Abc_NtkCo(pNtk, 0) );
260 261
        char * pName, * pCube, * pSop = (char *)pNode->pData;
        Vec_Int_t * vFanins = Vec_IntAlloc( Abc_ObjFaninNum(pNode) );
262 263 264 265 266 267 268 269 270 271 272 273 274
        int i, k, Value, nLits, Counter = 0;
        if ( pGia->vNamesIn )
        {
            // hash the names
            pNames = Abc_NamStart( 100, 16 );
            Vec_PtrForEachEntry( char *, pGia->vNamesIn, pName, i )
            {
                Value = Abc_NamStrFindOrAdd( pNames, pName, NULL );
                assert( Value == i+1 );
                //printf( "%s(%d) ", pName, i );
            }
            //printf( "\n" );
        }
275 276 277 278
        Abc_ObjForEachFanin( pNode, pFanin, i )
        {
            assert( Abc_ObjIsCi(pFanin) );
            pName = Abc_ObjName(pFanin);
279 280
            if ( pNames )
            {
281 282
                Value = Abc_NamStrFind(pNames, pName) - 1 - Gia_ManPiNum(pGia);
                if ( Value < 0 )
283 284 285 286 287 288 289
                {
                    if ( Counter++ == 0 )
                        printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
                    Value = i;
                }
            }
            else
290
            {
291 292 293 294 295 296 297 298 299 300 301
                for ( k = (int)strlen(pName)-1; k >= 0; k-- )
                    if ( pName[k] < '0' || pName[k] > '9' )
                        break;
                if ( k == (int)strlen(pName)-1 )
                {
                    if ( Counter++ == 0 )
                        printf( "Cannot read input name \"%s\" of fanin %d.\n", pName, i );
                    Value = i;
                }
                else 
                    Value = atoi(pName + k + 1);
302 303 304
            }
            Vec_IntPush( vFanins, Value );
        }
305 306 307 308
        if ( Counter )
            printf( "Cannot read names for %d inputs of the invariant.\n", Counter );
        if ( pNames )
            Abc_NamStop( pNames );
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
        assert( Vec_IntSize(vFanins) == Abc_ObjFaninNum(pNode) );
        vRes = Vec_IntAlloc( 1000 );
        Vec_IntPush( vRes, Abc_SopGetCubeNum(pSop) );
        Abc_SopForEachCube( pSop, Abc_ObjFaninNum(pNode), pCube )
        {
            nLits = 0;
            Abc_CubeForEachVar( pCube, Value, k )
                if ( Value != '-' )
                    nLits++;
            Vec_IntPush( vRes, nLits );
            Abc_CubeForEachVar( pCube, Value, k )
                if ( Value != '-' )
                    Vec_IntPush( vRes, Abc_Var2Lit(Vec_IntEntry(vFanins, k), (int)Value == '0') );
        }
        Vec_IntPush( vRes, nRegs );
        Vec_IntFree( vFanins );
    }
    return vRes;
}

329 330 331 332 333 334 335
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


ABC_NAMESPACE_IMPL_END