ioReadBench.c 13.6 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;
Alan Mishchenko committed
91 92 93
    unsigned uTruth[8];
    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) );
Alan Mishchenko committed
97 98 99 100

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

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

        // get the type of the line
114 115 116 117
        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
118 119 120
        else 
        {
            // get the node name and the node type
121
            pType = (char *)vTokens->pArray[1];
Alan Mishchenko committed
122 123
            if ( strncmp(pType, "DFF", 3) == 0 ) // works for both DFF and DFFRSE
            {
124
                pNode = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[2], (char *)vTokens->pArray[0] );
Alan Mishchenko committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
//                Abc_LatchSetInit0( pNode );
                if ( pType[3] == '0' )
                    Abc_LatchSetInit0( pNode );
                else if ( pType[3] == '1' )
                    Abc_LatchSetInit1( pNode );
                else
                    Abc_LatchSetInitDc( pNode );
            }
            else if ( strcmp(pType, "LUT") == 0 )
            {
                fLutsPresent = 1;
                ppNames = (char **)vTokens->pArray + 3;
                nNames  = vTokens->nSize - 3;
                // check the number of inputs
                if ( nNames > 8 )
                {
                    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
147
                pString = (char *)vTokens->pArray[2];
Alan Mishchenko committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
                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) )
                {
178
                    pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 );
179
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) );
Alan Mishchenko committed
180 181 182
                }
                else if ( Extra_TruthIsConst1(uTruth, nNames) )
                {
183
                    pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, 0 );
184
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) );
Alan Mishchenko committed
185 186 187 188
                }
                else
                {
                    // create the node
189
                    pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames );
Alan Mishchenko committed
190 191
                    assert( nNames > 0 );
                    if ( nNames > 1 )
192
                        Abc_ObjSetData( pNode, Abc_SopCreateFromTruth((Mem_Flex_t *)pNtk->pManFunc, nNames, uTruth) );
Alan Mishchenko committed
193
                    else if ( pString[0] == '2' )
194
                        Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) );
Alan Mishchenko committed
195
                    else if ( pString[0] == '1' )
196
                        Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) );
Alan Mishchenko committed
197 198 199 200 201 202 203 204 205
                    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
206 207 208
            else
            {
                // create a new node and add it to the network
Alan Mishchenko committed
209 210
                ppNames = (char **)vTokens->pArray + 2;
                nNames  = vTokens->nSize - 2;
211
                pNode = Io_ReadCreateNode( pNtk, (char *)vTokens->pArray[0], ppNames, nNames );
Alan Mishchenko committed
212 213
                // assign the cover
                if ( strcmp(pType, "AND") == 0 )
214
                    Abc_ObjSetData( pNode, Abc_SopCreateAnd((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) );
Alan Mishchenko committed
215
                else if ( strcmp(pType, "OR") == 0 )
216
                    Abc_ObjSetData( pNode, Abc_SopCreateOr((Mem_Flex_t *)pNtk->pManFunc, nNames, NULL) );
Alan Mishchenko committed
217
                else if ( strcmp(pType, "NAND") == 0 )
218
                    Abc_ObjSetData( pNode, Abc_SopCreateNand((Mem_Flex_t *)pNtk->pManFunc, nNames) );
Alan Mishchenko committed
219
                else if ( strcmp(pType, "NOR") == 0 )
220
                    Abc_ObjSetData( pNode, Abc_SopCreateNor((Mem_Flex_t *)pNtk->pManFunc, nNames) );
Alan Mishchenko committed
221
                else if ( strcmp(pType, "XOR") == 0 )
222
                    Abc_ObjSetData( pNode, Abc_SopCreateXor((Mem_Flex_t *)pNtk->pManFunc, nNames) );
Alan Mishchenko committed
223
                else if ( strcmp(pType, "NXOR") == 0 || strcmp(pType, "XNOR") == 0 )
224
                    Abc_ObjSetData( pNode, Abc_SopCreateNxor((Mem_Flex_t *)pNtk->pManFunc, nNames) );
Alan Mishchenko committed
225
                else if ( strncmp(pType, "BUF", 3) == 0 )
226
                    Abc_ObjSetData( pNode, Abc_SopCreateBuf((Mem_Flex_t *)pNtk->pManFunc) );
Alan Mishchenko committed
227
                else if ( strcmp(pType, "NOT") == 0 )
228
                    Abc_ObjSetData( pNode, Abc_SopCreateInv((Mem_Flex_t *)pNtk->pManFunc) );
Alan Mishchenko committed
229
                else if ( strncmp(pType, "MUX", 3) == 0 )
Alan Mishchenko committed
230
//                    Abc_ObjSetData( pNode, Abc_SopRegister(pNtk->pManFunc, "1-0 1\n-11 1\n") );
231
                    Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, "0-1 1\n11- 1\n") );
Alan Mishchenko committed
232
                else if ( strncmp(pType, "gnd", 3) == 0 )
233
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" ) );
Alan Mishchenko committed
234
                else if ( strncmp(pType, "vdd", 3) == 0 )
235
                    Abc_ObjSetData( pNode, Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" ) );
Alan Mishchenko committed
236
                else
Alan Mishchenko committed
237
                {
Alan Mishchenko committed
238 239
                    printf( "Io_ReadBenchNetwork(): Cannot determine gate type \"%s\" in line %d.\n", pType, Extra_FileReaderGetLineNumber(p, 0) );
                    Vec_StrFree( vString );
Alan Mishchenko committed
240 241 242 243 244 245 246
                    Abc_NtkDelete( pNtk );
                    return NULL;
                }
            }
        }
    }
    Extra_ProgressBarStop( pProgress );
Alan Mishchenko committed
247 248
    Vec_StrFree( vString );

Alan Mishchenko committed
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
    // 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
277

Alan Mishchenko committed
278
    Abc_NtkFinalizeRead( pNtk );
Alan Mishchenko committed
279 280 281 282 283 284 285 286 287 288

    // 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;
        }
289
        if ( !Abc_NtkToSop(pNtk, -1, ABC_INFINITY) )
Alan Mishchenko committed
290 291 292 293 294 295
        {
            printf( "Io_ReadBenchNetwork(): Converting to SOP has failed.\n" );
            Abc_NtkDelete( pNtk );
            return NULL;
        }
    }
Alan Mishchenko committed
296 297 298 299
    return pNtk;
}


Alan Mishchenko committed
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
/**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
359 360 361 362 363 364
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////



365 366
ABC_NAMESPACE_IMPL_END