ioReadBench.c 15.1 KB
Newer Older
Alan Mishchenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/**CFile****************************************************************

  FileName    [ioReadBench.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Command processing package.]

  Synopsis    [Procedures to read BENCH files.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - June 20, 2005.]

  Revision    [$Id: ioReadBench.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]

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

Alan Mishchenko committed
21
#include "ioAbc.h"
Alan Mishchenko committed
22

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29 30 31 32
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

static Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p );

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
33
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
34 35 36 37
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
38
  Synopsis    [Reads the network from a BENCH file.]
Alan Mishchenko committed
39

Alan Mishchenko committed
40
  Description []
Alan Mishchenko committed
41 42 43 44 45 46 47 48 49 50 51 52
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Io_ReadBench( char * pFileName, int fCheck )
{
    Extra_FileReader_t * p;
    Abc_Ntk_t * pNtk;

    // start the file
Alan Mishchenko committed
53
    p = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t,()=" );
Alan Mishchenko committed
54 55 56 57 58 59 60 61 62 63
    if ( p == NULL )
        return NULL;

    // read the network
    pNtk = Io_ReadBenchNetwork( p );
    Extra_FileReaderFree( p );
    if ( pNtk == NULL )
        return NULL;

    // make sure that everything is okay with the network structure
Alan Mishchenko committed
64
    if ( fCheck && !Abc_NtkCheckRead( pNtk ) )
Alan Mishchenko committed
65 66 67 68 69 70 71
    {
        printf( "Io_ReadBench: The network check has failed.\n" );
        Abc_NtkDelete( pNtk );
        return NULL;
    }
    return pNtk;
}
Alan Mishchenko committed
72

Alan Mishchenko committed
73 74
/**Function*************************************************************

Alan Mishchenko committed
75
  Synopsis    []
Alan Mishchenko committed
76

Alan Mishchenko committed
77
  Description []
Alan Mishchenko committed
78 79 80 81 82 83 84 85 86 87 88
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Io_ReadBenchNetwork( Extra_FileReader_t * p )
{
    ProgressBar * pProgress;
    Vec_Ptr_t * vTokens;
    Abc_Ntk_t * pNtk;
Alan Mishchenko committed
89
    Abc_Obj_t * pNode, * pNet;
Alan Mishchenko committed
90
    Vec_Str_t * vString;
91
    unsigned uTruth[2048];
Alan Mishchenko committed
92 93
    char * pType, ** ppNames, * pString;
    int iLine, nNames, nDigits, fLutsPresent = 0;
Alan Mishchenko committed
94 95
    
    // allocate the empty network
Alan Mishchenko committed
96
    pNtk = Abc_NtkStartRead( Extra_FileReaderGetFileName(p) );
97
    pNtk->nConstrs = 0;
Alan Mishchenko committed
98 99 100 101

    // go through the lines of the file
    vString = Vec_StrAlloc( 100 );
    pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p) );
102
    for ( iLine = 0; (vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p)); iLine++ )
Alan Mishchenko committed
103 104 105 106 107 108
    {
        Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p), NULL );

        if ( vTokens->nSize == 1 )
        {
            printf( "%s: Wrong input file format.\n", Extra_FileReaderGetFileName(p) );
Alan Mishchenko committed
109
            Vec_StrFree( vString );
Alan Mishchenko committed
110 111 112 113 114
            Abc_NtkDelete( pNtk );
            return NULL;
        }

        // get the type of the line
115 116 117 118
        if ( strncmp( (char *)vTokens->pArray[0], "INPUT", 5 ) == 0 )
            Io_ReadCreatePi( pNtk, (char *)vTokens->pArray[1] );
        else if ( strncmp( (char *)vTokens->pArray[0], "OUTPUT", 5 ) == 0 )
            Io_ReadCreatePo( pNtk, (char *)vTokens->pArray[1] );
Alan Mishchenko committed
119 120 121
        else 
        {
            // get the node name and the node type
122
            pType = (char *)vTokens->pArray[1];
Alan Mishchenko committed
123 124
            if ( strncmp(pType, "DFF", 3) == 0 ) // works for both DFF and DFFRSE
            {
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
                if ( Vec_PtrSize(vTokens) == 6 )
                {
                    // create primary input to represent flop output
                    char pNetName[1000]; char * pName; int i;
                    char * pFlopOut   = (char *)vTokens->pArray[0];
                    Abc_Obj_t * pNet  = Abc_NtkFindOrCreateNet( pNtk, pFlopOut );
                    Abc_Obj_t * pTerm = Abc_NtkCreatePi( pNtk );
                    Abc_ObjAddFanin( pNet, pTerm );
                    // create four primary outputs to represent flop inputs
                    Vec_PtrForEachEntryStart( char *, vTokens, pName, i, 2 )
                    {
                        sprintf( pNetName, "%s_%s", pFlopOut, pName );
                        pNet  = Abc_NtkFindOrCreateNet( pNtk, pName );
                        pTerm = Abc_NtkCreateNodeBuf( pNtk, pNet );
                        pNet  = Abc_NtkFindOrCreateNet( pNtk, pNetName );
                        Abc_ObjAddFanin( pNet, pTerm );
                        pTerm = Abc_NtkCreatePo( pNtk );
                        Abc_ObjAddFanin( pTerm, pNet );
                    }
144
                    pNtk->nConstrs++;
145
                }
Alan Mishchenko committed
146
                else
147 148 149 150 151 152 153 154 155 156
                {
                    pNode = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[2], (char *)vTokens->pArray[0] );
    //                Abc_LatchSetInit0( pNode );
                    if ( pType[3] == '0' )
                        Abc_LatchSetInit0( pNode );
                    else if ( pType[3] == '1' )
                        Abc_LatchSetInit1( pNode );
                    else
                        Abc_LatchSetInitDc( pNode );
                }
Alan Mishchenko committed
157 158 159 160 161 162 163
            }
            else if ( strcmp(pType, "LUT") == 0 )
            {
                fLutsPresent = 1;
                ppNames = (char **)vTokens->pArray + 3;
                nNames  = vTokens->nSize - 3;
                // check the number of inputs
164
                if ( nNames > 15 )
Alan Mishchenko committed
165 166 167 168 169 170 171
                {
                    printf( "%s: Currently cannot read truth tables with more than 8 inputs (%d).\n", Extra_FileReaderGetFileName(p), nNames );
                    Vec_StrFree( vString );
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
                // get the hex string
172
                pString = (char *)vTokens->pArray[2];
Alan Mishchenko committed
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
                if ( strncmp( pString, "0x", 2 ) )
                {
                    printf( "%s: The LUT signature (%s) does not look like a hexadecimal beginning with \"0x\".\n", Extra_FileReaderGetFileName(p), pString );
                    Vec_StrFree( vString );
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
                pString += 2;
                // pad the string with zero's if needed
                nDigits = (1 << nNames) / 4;
                if ( nDigits == 0 )
                    nDigits = 1;
                if ( strlen(pString) < (unsigned)nDigits )
                {
                    Vec_StrFill( vString, nDigits - strlen(pString), '0' );
                    Vec_StrPrintStr( vString, pString );
                    Vec_StrPush( vString, 0 );
                    pString = Vec_StrArray( vString );
                }
                // read the hex number from the string
                if ( !Extra_ReadHexadecimal( uTruth, pString, nNames ) )
                {
                    printf( "%s: Reading hexadecimal number (%s) has failed.\n", Extra_FileReaderGetFileName(p), pString );
                    Vec_StrFree( vString );
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
                // check if the node is a constant node
                if ( Extra_TruthIsConst0(uTruth, nNames) )
                {
203
                    pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 );
204
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) );
Alan Mishchenko committed
205 206 207
                }
                else if ( Extra_TruthIsConst1(uTruth, nNames) )
                {
208
                    pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 );
209
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) );
Alan Mishchenko committed
210 211 212 213
                }
                else
                {
                    // create the node
214
                    pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames );
Alan Mishchenko committed
215 216
                    assert( nNames > 0 );
                    if ( nNames > 1 )
217
                        Abc_ObjSetData( pNode, Abc_SopCreateFromTruth((Mem_Flex_t *)pNtk->pManFunc, nNames, uTruth) );
Alan Mishchenko committed
218
                    else if ( pString[0] == '2' )
219
                        Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) );
Alan Mishchenko committed
220
                    else if ( pString[0] == '1' )
221
                        Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) );
Alan Mishchenko committed
222 223 224 225 226 227 228 229 230
                    else
                    {
                        printf( "%s: Reading truth table (%s) of single-input node has failed.\n", Extra_FileReaderGetFileName(p), pString );
                        Vec_StrFree( vString );
                        Abc_NtkDelete( pNtk );
                        return NULL;
                    }
                }
            }
Alan Mishchenko committed
231 232 233
            else
            {
                // create a new node and add it to the network
Alan Mishchenko committed
234 235
                ppNames = (char **)vTokens->pArray + 2;
                nNames  = vTokens->nSize - 2;
236
                pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames );
Alan Mishchenko committed
237
                // assign the cover
238
                if ( strcmp(pType, "AND") == 0 || strcmp(pType, "and") == 0 )
239
                    Abc_ObjSetData( pNode, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) );
240
                else if ( strcmp(pType, "OR") == 0 || strcmp(pType, "or") == 0 )
241
                    Abc_ObjSetData( pNode, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) );
242
                else if ( strcmp(pType, "NAND") == 0 || strcmp(pType, "nand") == 0 )
243
                    Abc_ObjSetData( pNode, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, nNames) );
244
                else if ( strcmp(pType, "NOR") == 0 || strcmp(pType, "nor") == 0 )
245
                    Abc_ObjSetData( pNode, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, nNames) );
246
                else if ( strcmp(pType, "XOR") == 0 || strcmp(pType, "xor") == 0 )
247
                    Abc_ObjSetData( pNode, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, nNames) );
248
                else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 || strcmp(pType, "nxor") == 0 || strcmp(pType, "xnor") == 0 )
249
                    Abc_ObjSetData( pNode, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, nNames) );
250
                else if ( strncmp(pType, "BUF", 3) == 0 || strcmp(pType, "buf") == 0 )
251
                    Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) );
252
                else if ( strcmp(pType, "NOT") == 0 || strcmp(pType, "not") == 0 )
253
                    Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) );
254
                else if ( strncmp(pType, "MUX", 3) == 0 || strcmp(pType, "mux") == 0 )
Alan Mishchenko committed
255
//                    Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") );
256
                    Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, "0-1 1\n11- 1\n") );
Alan Mishchenko committed
257
                else if ( strncmp(pType, "gnd", 3) == 0 )
258
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) );
Alan Mishchenko committed
259
                else if ( strncmp(pType, "vdd", 3) == 0 )
260
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) );
Alan Mishchenko committed
261
                else
Alan Mishchenko committed
262
                {
Alan Mishchenko committed
263 264
                    printf( "Io_ReadBenchNetwork(): Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) );
                    Vec_StrFree( vString );
Alan Mishchenko committed
265 266 267 268 269 270 271
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
            }
        }
    }
    Extra_ProgressBarStop( pProgress );
Alan Mishchenko committed
272 273
    Vec_StrFree( vString );

Alan Mishchenko committed
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
    // check if constant 0 is present
    if ( (pNet = Abc_NtkFindNet( pNtk, "gnd" )) )
    {
        if ( Abc_ObjFaninNum(pNet) == 0 )
            Io_ReadCreateConst( pNtk, "gnd", 0 );
    }
    if ( (pNet = Abc_NtkFindNet( pNtk, "1" )) )
    {
        if ( Abc_ObjFaninNum(pNet) == 0 )
        {
            printf( "Io_ReadBenchNetwork(): Adding constant 0 fanin to non-driven net \"1\".\n" );
            Io_ReadCreateConst( pNtk, "1", 0 );
        }
    }
    // check if constant 1 is present
    if ( (pNet = Abc_NtkFindNet( pNtk, "vdd" )) )
    {
        if ( Abc_ObjFaninNum(pNet) == 0 )
            Io_ReadCreateConst( pNtk, "vdd", 1 );
    }
    if ( (pNet = Abc_NtkFindNet( pNtk, "2" )) )
    {
        if ( Abc_ObjFaninNum(pNet) == 0 )
        {
            printf( "Io_ReadBenchNetwork(): Adding constant 1 fanin to non-driven net \"2\".\n" );
            Io_ReadCreateConst( pNtk, "2", 1 );
        }
    }
Alan Mishchenko committed
302

Alan Mishchenko committed
303
    Abc_NtkFinalizeRead( pNtk );
Alan Mishchenko committed
304 305 306 307 308 309 310 311 312 313

    // if LUTs are present, collapse the truth tables into cubes
    if ( fLutsPresent )
    {
        if ( !Abc_NtkToBdd(pNtk) )
        {
            printf( "Io_ReadBenchNetwork(): Converting to BDD has failed.\n" );
            Abc_NtkDelete( pNtk );
            return NULL;
        }
314
        if ( !Abc_NtkToSop(pNtk, -1, ABC_INFINITY) )
Alan Mishchenko committed
315 316 317 318 319 320
        {
            printf( "Io_ReadBenchNetwork(): Converting to SOP has failed.\n" );
            Abc_NtkDelete( pNtk );
            return NULL;
        }
    }
Alan Mishchenko committed
321 322 323 324
    return pNtk;
}


Alan Mishchenko committed
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
/**Function*************************************************************

  Synopsis    [Reads initial state in BENCH format.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Io_ReadBenchInit( Abc_Ntk_t * pNtk, char * pFileName )
{
    char pBuffer[1000];
    FILE * pFile;
    char * pToken;
    Abc_Obj_t * pObj;
    int Num;
    pFile = fopen( pFileName, "r" );
    if ( pFile == NULL )
    {
        printf( "Io_ReadBenchInit(): Failed to open file \"%s\".\n", pFileName );
        return;
    }
    while ( fgets( pBuffer, 999, pFile ) )
    {
        pToken = strtok( pBuffer, " \n\t\r" );
        // find the latch output
        Num = Nm_ManFindIdByName( pNtk->pManName, pToken, ABC_OBJ_BO );
        if ( Num < 0 )
        {
            printf( "Io_ReadBenchInit(): Cannot find register with output %s.\n", pToken );
            continue;
        }
        pObj = Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) );
        if ( !Abc_ObjIsLatch(pObj) )
        {
            printf( "Io_ReadBenchInit(): The signal is not a register output %s.\n", pToken );
            continue;
        }
        // assign the new init state
        pToken = strtok( NULL, " \n\t\r" );
        if ( pToken[0] == '0' )
            Abc_LatchSetInit0( pObj );
        else if ( pToken[0] == '1' )
            Abc_LatchSetInit1( pObj );
        else if ( pToken[0] == '2' )
            Abc_LatchSetInitDc( pObj );
        else
        {
            printf( "Io_ReadBenchInit(): The signal %s has unknown initial value (%s).\n", 
                Abc_ObjName(Abc_ObjFanout0(pObj)), pToken );
            continue;
        }
    }
    fclose( pFile );
}


Alan Mishchenko committed
384 385 386 387 388 389
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////



390 391
ABC_NAMESPACE_IMPL_END