ioReadBlif.c 53 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    [ioReadBlif.c]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Command processing package.]

  Synopsis    [Procedures to read BLIF files.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

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

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

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

Alan Mishchenko committed
21
#include "ioAbc.h"
22 23
#include "base/main/main.h"
#include "map/mio/mio.h"
Alan Mishchenko committed
24

25 26 27
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
28 29 30 31 32 33 34 35
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

typedef struct Io_ReadBlif_t_        Io_ReadBlif_t;   // all reading info
struct Io_ReadBlif_t_
{
    // general info about file
Alan Mishchenko committed
36 37
    char *               pFileName;    // the name of the file
    Extra_FileReader_t * pReader;      // the input file reader
Alan Mishchenko committed
38
    // current processing info
Alan Mishchenko committed
39 40
    Abc_Ntk_t *          pNtkMaster;   // the primary network
    Abc_Ntk_t *          pNtkCur;      // the primary network
Alan Mishchenko committed
41
    int                  LineCur;      // the line currently parsed
Alan Mishchenko committed
42
    // temporary storage for tokens
Alan Mishchenko committed
43
    Vec_Ptr_t *          vTokens;      // the current tokens
Alan Mishchenko committed
44 45
    Vec_Ptr_t *          vNewTokens;   // the temporary storage for the tokens
    Vec_Str_t *          vCubes;       // the temporary storage for the tokens
Alan Mishchenko committed
46
    // the error message
Alan Mishchenko committed
47 48
    FILE *               Output;       // the output stream
    char                 sError[1000]; // the error string generated during parsing
Alan Mishchenko committed
49
    int                  fError;       // set to 1 when error occurs
Alan Mishchenko committed
50 51 52 53 54 55
};

static Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName );
static void Io_ReadBlifFree( Io_ReadBlif_t * p );
static void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p );
static Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p );
Alan Mishchenko committed
56
static char * Io_ReadBlifCleanName( char * pName );
Alan Mishchenko committed
57

Alan Mishchenko committed
58 59
static Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p );
static Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p );
Alan Mishchenko committed
60 61 62 63
static int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens );
Alan Mishchenko committed
64
static int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
Alan Mishchenko committed
65
static int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
Alan Mishchenko committed
66
static int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
67
static int Io_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
Alan Mishchenko committed
68
static int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
69
static int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
70 71 72 73
static int Io_ReadBlifNetworkInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
static int Io_ReadBlifNetworkDefaultOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
74
static int Io_ReadBlifNetworkAndGateDelay( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens );
Alan Mishchenko committed
75
static int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster );
Alan Mishchenko committed
76 77

////////////////////////////////////////////////////////////////////////
Alan Mishchenko committed
78
///                     FUNCTION DEFINITIONS                         ///
Alan Mishchenko committed
79 80 81 82
////////////////////////////////////////////////////////////////////////

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

Alan Mishchenko committed
83
  Synopsis    [Reads the (hierarchical) network from the BLIF file.]
Alan Mishchenko committed
84

Alan Mishchenko committed
85
  Description []
Alan Mishchenko committed
86 87 88 89 90 91 92 93 94
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Abc_Ntk_t * Io_ReadBlif( char * pFileName, int fCheck )
{
    Io_ReadBlif_t * p;
Alan Mishchenko committed
95
    Abc_Ntk_t * pNtk;
Alan Mishchenko committed
96 97 98 99 100 101

    // start the file
    p = Io_ReadBlifFile( pFileName );
    if ( p == NULL )
        return NULL;

Alan Mishchenko committed
102
    // read the hierarchical network
Alan Mishchenko committed
103 104 105 106 107 108
    pNtk = Io_ReadBlifNetwork( p );
    if ( pNtk == NULL )
    {
        Io_ReadBlifFree( p );
        return NULL;
    }
Alan Mishchenko committed
109
    pNtk->pSpec = Extra_UtilStrsav( pFileName );
110
    Abc_NtkTimeInitialize( pNtk, NULL );
Alan Mishchenko committed
111 112 113
    Io_ReadBlifFree( p );

    // make sure that everything is okay with the network structure
Alan Mishchenko committed
114
    if ( fCheck && !Abc_NtkCheckRead( pNtk ) )
Alan Mishchenko committed
115 116 117 118 119 120 121 122 123 124
    {
        printf( "Io_ReadBlif: The network check has failed.\n" );
        Abc_NtkDelete( pNtk );
        return NULL;
    }
    return pNtk;
}

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

Alan Mishchenko committed
125
  Synopsis    [Iteratively reads several networks in the hierarchical design.]
Alan Mishchenko committed
126 127 128 129 130 131 132 133

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
134
Abc_Ntk_t * Io_ReadBlifNetwork( Io_ReadBlif_t * p )
Alan Mishchenko committed
135
{
Alan Mishchenko committed
136
    Abc_Ntk_t * pNtk, * pNtkMaster;
Alan Mishchenko committed
137

Alan Mishchenko committed
138 139
    // read the name of the master network
    p->vTokens = Io_ReadBlifGetTokens(p);
140
    if ( p->vTokens == NULL || strcmp( (char *)p->vTokens->pArray[0], ".model" ) )
Alan Mishchenko committed
141
    {
Alan Mishchenko committed
142 143 144 145
        p->LineCur = 0;
        sprintf( p->sError, "Wrong input file format." );
        Io_ReadBlifPrintErrorMessage( p );
        return NULL;
Alan Mishchenko committed
146
    }
Alan Mishchenko committed
147

Alan Mishchenko committed
148 149 150
    // read networks (with EXDC) 
    pNtkMaster = NULL;
    while ( p->vTokens )
Alan Mishchenko committed
151
    {
Alan Mishchenko committed
152 153 154 155
        // read the network and its EXDC if present
        pNtk = Io_ReadBlifNetworkOne( p );
        if ( pNtk == NULL )
            break;
156
        if ( p->vTokens && strcmp((char *)p->vTokens->pArray[0], ".exdc") == 0 )
Alan Mishchenko committed
157
        {
Alan Mishchenko committed
158 159 160
            pNtk->pExdc = Io_ReadBlifNetworkOne( p );
            if ( pNtk->pExdc == NULL )
                break;
161
            Abc_NtkFinalizeRead( pNtk->pExdc );
Alan Mishchenko committed
162 163 164 165 166
        }
        // add this network as part of the hierarchy
        if ( pNtkMaster == NULL ) // no master network so far
        {
            p->pNtkMaster = pNtkMaster = pNtk;
Alan Mishchenko committed
167
            continue;
Alan Mishchenko committed
168
        }
Alan Mishchenko committed
169 170 171 172 173 174 175 176 177 178 179 180 181 182
/*
        // make sure hierarchy does not have the network with this name
        if ( pNtkMaster->tName2Model && stmm_is_member( pNtkMaster->tName2Model, pNtk->pName ) )
        {
            p->LineCur = 0;
            sprintf( p->sError, "Model %s is multiply defined in the file.", pNtk->pName );
            Io_ReadBlifPrintErrorMessage( p );
            Abc_NtkDelete( pNtk );
            Abc_NtkDelete( pNtkMaster );
            pNtkMaster = NULL;
            return NULL;
        }
        // add the network to the hierarchy
        if ( pNtkMaster->tName2Model == NULL )
183
            pNtkMaster->tName2Model = stmm_init_table((int (*)(void))strcmp, (int (*)(void))stmm_strhash);
Alan Mishchenko committed
184 185
        stmm_insert( pNtkMaster->tName2Model, pNtk->pName, (char *)pNtk );
*/
Alan Mishchenko committed
186
    }
Alan Mishchenko committed
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
/*
    // if there is a hierarchy, connect the boxes
    if ( pNtkMaster && pNtkMaster->tName2Model )
    {
        if ( Io_ReadBlifNetworkConnectBoxes( p, pNtkMaster ) )
        {
            Abc_NtkDelete( pNtkMaster );
            return NULL;
        }
    }
    else 
*/
    if ( !p->fError )
        Abc_NtkFinalizeRead( pNtkMaster );
    // return the master network
    return pNtkMaster;
Alan Mishchenko committed
203 204 205 206
}

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

Alan Mishchenko committed
207
  Synopsis    [Reads one (main or exdc) network from the BLIF file.]
Alan Mishchenko committed
208 209 210 211 212 213 214 215

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
216
Abc_Ntk_t * Io_ReadBlifNetworkOne( Io_ReadBlif_t * p )
Alan Mishchenko committed
217
{
Alan Mishchenko committed
218
    ProgressBar * pProgress = NULL;
Alan Mishchenko committed
219 220
    Abc_Ntk_t * pNtk;
    char * pDirective;
Alan Mishchenko committed
221 222
    int iLine, fTokensReady, fStatus;

Alan Mishchenko committed
223 224 225 226 227
    // make sure the tokens are present
    assert( p->vTokens != NULL );

    // create the new network
    p->pNtkCur = pNtk = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
Alan Mishchenko committed
228
    // read the model name
229
    if ( strcmp( (char *)p->vTokens->pArray[0], ".model" ) == 0 )
Alan Mishchenko committed
230 231 232 233 234 235 236 237 238
    {
        char * pToken, * pPivot;
        if ( Vec_PtrSize(p->vTokens) != 2 )
        {
            p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
            sprintf( p->sError, "The .model line does not have exactly two entries." );
            Io_ReadBlifPrintErrorMessage( p );
            return NULL;
        }
239
        for ( pPivot = pToken = (char *)Vec_PtrEntry(p->vTokens, 1); *pToken; pToken++ )
Alan Mishchenko committed
240 241 242 243
            if ( *pToken == '/' || *pToken == '\\' )
                pPivot = pToken+1;
        pNtk->pName = Extra_UtilStrsav( pPivot );
    }
244
    else if ( strcmp( (char *)p->vTokens->pArray[0], ".exdc" ) != 0 ) 
Alan Mishchenko committed
245
    {
Alan Mishchenko committed
246
        printf( "%s: File parsing skipped after line %d (\"%s\").\n", p->pFileName, 
Alan Mishchenko committed
247
            Extra_FileReaderGetLineNumber(p->pReader, 0), (char*)p->vTokens->pArray[0] );
Alan Mishchenko committed
248 249 250
        Abc_NtkDelete(pNtk);
        p->pNtkCur = NULL;
        return NULL;
Alan Mishchenko committed
251
    }
Alan Mishchenko committed
252 253

    // read the inputs/outputs
Alan Mishchenko committed
254
    if ( p->pNtkMaster == NULL )
Alan Mishchenko committed
255
        pProgress = Extra_ProgressBarStart( stdout, Extra_FileReaderGetFileSize(p->pReader) );
Alan Mishchenko committed
256
    fTokensReady = fStatus = 0;
Alan Mishchenko committed
257
    for ( iLine = 0; fTokensReady || (p->vTokens = Io_ReadBlifGetTokens(p)); iLine++ )
Alan Mishchenko committed
258
    {
Alan Mishchenko committed
259
        if ( p->pNtkMaster == NULL && iLine % 1000 == 0 )
Alan Mishchenko committed
260
            Extra_ProgressBarUpdate( pProgress, Extra_FileReaderGetCurPosition(p->pReader), NULL );
Alan Mishchenko committed
261 262 263

        // consider different line types
        fTokensReady = 0;
264
        pDirective = (char *)p->vTokens->pArray[0];
Alan Mishchenko committed
265
        if ( !strcmp( pDirective, ".names" ) )
Alan Mishchenko committed
266
            { fStatus = Io_ReadBlifNetworkNames( p, &p->vTokens ); fTokensReady = 1; }
Alan Mishchenko committed
267
        else if ( !strcmp( pDirective, ".gate" ) )
Alan Mishchenko committed
268
            fStatus = Io_ReadBlifNetworkGate( p, p->vTokens );
Alan Mishchenko committed
269
        else if ( !strcmp( pDirective, ".latch" ) )
Alan Mishchenko committed
270
            fStatus = Io_ReadBlifNetworkLatch( p, p->vTokens );
Alan Mishchenko committed
271
        else if ( !strcmp( pDirective, ".inputs" ) )
Alan Mishchenko committed
272
            fStatus = Io_ReadBlifNetworkInputs( p, p->vTokens );
Alan Mishchenko committed
273
        else if ( !strcmp( pDirective, ".outputs" ) )
Alan Mishchenko committed
274
            fStatus = Io_ReadBlifNetworkOutputs( p, p->vTokens );
Alan Mishchenko committed
275
        else if ( !strcmp( pDirective, ".input_arrival" ) )
Alan Mishchenko committed
276
            fStatus = Io_ReadBlifNetworkInputArrival( p, p->vTokens );
277 278
        else if ( !strcmp( pDirective, ".output_required" ) )
            fStatus = Io_ReadBlifNetworkOutputRequired( p, p->vTokens );
Alan Mishchenko committed
279
        else if ( !strcmp( pDirective, ".default_input_arrival" ) )
Alan Mishchenko committed
280
            fStatus = Io_ReadBlifNetworkDefaultInputArrival( p, p->vTokens );
281 282
        else if ( !strcmp( pDirective, ".default_output_required" ) )
            fStatus = Io_ReadBlifNetworkDefaultOutputRequired( p, p->vTokens );
283 284 285 286 287 288 289 290
        else if ( !strcmp( pDirective, ".input_drive" ) )
            fStatus = Io_ReadBlifNetworkInputDrive( p, p->vTokens );
        else if ( !strcmp( pDirective, ".output_load" ) )
            fStatus = Io_ReadBlifNetworkOutputLoad( p, p->vTokens );
        else if ( !strcmp( pDirective, ".default_input_drive" ) )
            fStatus = Io_ReadBlifNetworkDefaultInputDrive( p, p->vTokens );
        else if ( !strcmp( pDirective, ".default_output_load" ) )
            fStatus = Io_ReadBlifNetworkDefaultOutputLoad( p, p->vTokens );
291 292
        else if ( !strcmp( pDirective, ".and_gate_delay" ) )
            fStatus = Io_ReadBlifNetworkAndGateDelay( p, p->vTokens );
Alan Mishchenko committed
293 294
//        else if ( !strcmp( pDirective, ".subckt" ) )
//            fStatus = Io_ReadBlifNetworkSubcircuit( p, p->vTokens );
Alan Mishchenko committed
295
        else if ( !strcmp( pDirective, ".exdc" ) )
Alan Mishchenko committed
296
            break;
Alan Mishchenko committed
297
        else if ( !strcmp( pDirective, ".end" ) )
Alan Mishchenko committed
298 299
        {
            p->vTokens = Io_ReadBlifGetTokens(p);
Alan Mishchenko committed
300
            break;
Alan Mishchenko committed
301 302 303 304 305
        }
        else if ( !strcmp( pDirective, ".blackbox" ) )
        {
            pNtk->ntkType = ABC_NTK_NETLIST;
            pNtk->ntkFunc = ABC_FUNC_BLACKBOX;
306
            Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 );
Alan Mishchenko committed
307 308
            pNtk->pManFunc = NULL;
        }
Alan Mishchenko committed
309 310
        else
            printf( "%s (line %d): Skipping directive \"%s\".\n", p->pFileName, 
Alan Mishchenko committed
311
                Extra_FileReaderGetLineNumber(p->pReader, 0), pDirective );
Alan Mishchenko committed
312
        if ( p->vTokens == NULL ) // some files do not have ".end" in the end
Alan Mishchenko committed
313 314
            break;
        if ( fStatus == 1 )
Alan Mishchenko committed
315 316 317
        {
            Extra_ProgressBarStop( pProgress );
            Abc_NtkDelete( pNtk );
Alan Mishchenko committed
318
            return NULL;
Alan Mishchenko committed
319
        }
Alan Mishchenko committed
320
    }
Alan Mishchenko committed
321
    if ( p->pNtkMaster == NULL )
Alan Mishchenko committed
322
        Extra_ProgressBarStop( pProgress );
Alan Mishchenko committed
323
    return pNtk;
Alan Mishchenko committed
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkInputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    int i;
    for ( i = 1; i < vTokens->nSize; i++ )
341
        Io_ReadCreatePi( p->pNtkCur, (char *)vTokens->pArray[i] );
Alan Mishchenko committed
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkOutputs( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    int i;
    for ( i = 1; i < vTokens->nSize; i++ )
360
        Io_ReadCreatePo( p->pNtkCur, (char *)vTokens->pArray[i] );
Alan Mishchenko committed
361 362 363 364 365 366 367 368 369 370 371 372 373 374
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
375 376 377
int Io_ReadBlifNetworkLatch( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{ 
    Abc_Ntk_t * pNtk = p->pNtkCur;
Alan Mishchenko committed
378
    Abc_Obj_t * pLatch;
Alan Mishchenko committed
379 380 381 382 383 384 385 386
    int ResetValue;
    if ( vTokens->nSize < 3 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "The .latch line does not have enough tokens." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
Alan Mishchenko committed
387
    // create the latch
388
    pLatch = Io_ReadCreateLatch( pNtk, (char *)vTokens->pArray[1], (char *)vTokens->pArray[2] );
Alan Mishchenko committed
389 390
    // get the latch reset value
    if ( vTokens->nSize == 3 )
Alan Mishchenko committed
391
        Abc_LatchSetInitDc( pLatch );
Alan Mishchenko committed
392 393
    else
    {
394
        ResetValue = atoi((char *)vTokens->pArray[vTokens->nSize-1]);
Alan Mishchenko committed
395 396 397
        if ( ResetValue != 0 && ResetValue != 1 && ResetValue != 2 )
        {
            p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
Alan Mishchenko committed
398
            sprintf( p->sError, "The .latch line has an unknown reset value (%s).", (char*)vTokens->pArray[3] );
Alan Mishchenko committed
399 400 401
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
Alan Mishchenko committed
402 403 404 405 406 407
        if ( ResetValue == 0 )
            Abc_LatchSetInit0( pLatch );
        else if ( ResetValue == 1 )
            Abc_LatchSetInit1( pLatch );
        else if ( ResetValue == 2 )
            Abc_LatchSetInitDc( pLatch );
Alan Mishchenko committed
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
    }
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkNames( Io_ReadBlif_t * p, Vec_Ptr_t ** pvTokens )
{
    Vec_Ptr_t * vTokens = *pvTokens;
Alan Mishchenko committed
426
    Abc_Ntk_t * pNtk = p->pNtkCur;
Alan Mishchenko committed
427 428 429
    Abc_Obj_t * pNode;
    char * pToken, Char, ** ppNames;
    int nFanins, nNames;
Alan Mishchenko committed
430 431 432 433 434 435 436 437 438

    // create a new node and add it to the network
    if ( vTokens->nSize < 2 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "The .names line has less than two tokens." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
Alan Mishchenko committed
439 440 441 442 443

    // create the node
    ppNames = (char **)vTokens->pArray + 1;
    nNames  = vTokens->nSize - 2;
    pNode   = Io_ReadCreateNode( pNtk, ppNames[nNames], ppNames, nNames );
Alan Mishchenko committed
444 445 446 447 448

    // derive the functionality of the node
    p->vCubes->nSize = 0;
    nFanins = vTokens->nSize - 2;
    if ( nFanins == 0 )
Alan Mishchenko committed
449
    {
Alan Mishchenko committed
450
        while ( (vTokens = Io_ReadBlifGetTokens(p)) )
Alan Mishchenko committed
451
        {
452
            pToken = (char *)vTokens->pArray[0];
Alan Mishchenko committed
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
            if ( pToken[0] == '.' )
                break;
            // read the cube
            if ( vTokens->nSize != 1 )
            {
                p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
                sprintf( p->sError, "The number of tokens in the constant cube is wrong." );
                Io_ReadBlifPrintErrorMessage( p );
                return 1;
            }
            // create the cube
            Char = ((char *)vTokens->pArray[0])[0];
            Vec_StrPush( p->vCubes, ' ' );
            Vec_StrPush( p->vCubes, Char );
            Vec_StrPush( p->vCubes, '\n' );
        }
Alan Mishchenko committed
469
    }
Alan Mishchenko committed
470
    else
Alan Mishchenko committed
471
    {
Alan Mishchenko committed
472
        while ( (vTokens = Io_ReadBlifGetTokens(p)) )
Alan Mishchenko committed
473
        {
474
            pToken = (char *)vTokens->pArray[0];
Alan Mishchenko committed
475 476 477 478 479 480 481 482 483 484 485
            if ( pToken[0] == '.' )
                break;
            // read the cube
            if ( vTokens->nSize != 2 )
            {
                p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
                sprintf( p->sError, "The number of tokens in the cube is wrong." );
                Io_ReadBlifPrintErrorMessage( p );
                return 1;
            }
            // create the cube
486
            Vec_StrPrintStr( p->vCubes, (char *)vTokens->pArray[0] );
Alan Mishchenko committed
487 488
            // check the char 
            Char = ((char *)vTokens->pArray[1])[0];
Alan Mishchenko committed
489
            if ( Char != '0' && Char != '1' && Char != 'x' && Char != 'n' )
Alan Mishchenko committed
490 491 492 493 494 495 496 497 498 499
            {
                p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
                sprintf( p->sError, "The output character in the constant cube is wrong." );
                Io_ReadBlifPrintErrorMessage( p );
                return 1;
            }
            Vec_StrPush( p->vCubes, ' ' );
            Vec_StrPush( p->vCubes, Char );
            Vec_StrPush( p->vCubes, '\n' );
        }
Alan Mishchenko committed
500
    }
Alan Mishchenko committed
501 502 503 504 505 506 507 508 509
    // if there is nothing there
    if ( p->vCubes->nSize == 0 )
    {
        // create an empty cube
        Vec_StrPush( p->vCubes, ' ' );
        Vec_StrPush( p->vCubes, '0' );
        Vec_StrPush( p->vCubes, '\n' );
    }
    Vec_StrPush( p->vCubes, 0 );
Alan Mishchenko committed
510

Alan Mishchenko committed
511
    // set the pointer to the functionality of the node
512
    Abc_ObjSetData( pNode, Abc_SopRegister((Mem_Flex_t *)pNtk->pManFunc, p->vCubes->pArray) );
Alan Mishchenko committed
513

Alan Mishchenko committed
514
    // check the size
515
    if ( Abc_ObjFaninNum(pNode) != Abc_SopGetVarNum((char *)Abc_ObjData(pNode)) )
Alan Mishchenko committed
516 517 518
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "The number of fanins (%d) of node %s is different from SOP size (%d).", 
519
            Abc_ObjFaninNum(pNode), Abc_ObjName(Abc_ObjFanout(pNode,0)), Abc_SopGetVarNum((char *)Abc_ObjData(pNode)) );
Alan Mishchenko committed
520 521 522 523
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }

Alan Mishchenko committed
524 525 526 527 528
    // return the last array of tokens
    *pvTokens = vTokens;
    return 0;
}

Alan Mishchenko committed
529 530 531 532 533 534 535 536 537 538 539
/**Function*************************************************************

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
540
int Io_ReadBlifReorderFormalNames( Vec_Ptr_t * vTokens, Mio_Gate_t * pGate, Mio_Gate_t * pTwin )
Alan Mishchenko committed
541 542 543 544 545
{
    Mio_Pin_t * pGatePin;
    char * pName, * pNamePin;
    int i, k, nSize, Length;
    nSize = Vec_PtrSize(vTokens);
546 547
    if ( pTwin == NULL )
    {
548
        if ( nSize - 3 != Mio_GateReadPinNum(pGate) )
549 550 551 552
            return 0;
    }
    else
    {
553
        if ( nSize - 3 != Mio_GateReadPinNum(pGate) && nSize - 4 != Mio_GateReadPinNum(pGate) )
554 555
            return 0;
    }
Alan Mishchenko committed
556 557 558 559 560
    // check if the names are in order
    for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
    {
        pNamePin = Mio_PinReadName(pGatePin);
        Length = strlen(pNamePin);
561
        pName = (char *)Vec_PtrEntry(vTokens, i+2);
Alan Mishchenko committed
562 563 564 565
        if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
            continue;
        break;
    }
566
    if ( pTwin == NULL )
Alan Mishchenko committed
567
    {
568
        if ( i == Mio_GateReadPinNum(pGate) )
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
            return 1;
        // reorder the pins
        for ( pGatePin = Mio_GateReadPins(pGate), i = 0; pGatePin; pGatePin = Mio_PinReadNext(pGatePin), i++ )
        {
            pNamePin = Mio_PinReadName(pGatePin);
            Length = strlen(pNamePin);
            for ( k = 2; k < nSize; k++ )
            {
                pName = (char *)Vec_PtrEntry(vTokens, k);
                if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
                {
                    Vec_PtrPush( vTokens, pName );
                    break;
                }
            }
        }
        pNamePin = Mio_GateReadOutName(pGate);
Alan Mishchenko committed
586 587 588
        Length = strlen(pNamePin);
        for ( k = 2; k < nSize; k++ )
        {
589
            pName = (char *)Vec_PtrEntry(vTokens, k);
Alan Mishchenko committed
590 591 592 593 594 595
            if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' )
            {
                Vec_PtrPush( vTokens, pName );
                break;
            }
        }
596 597 598 599 600
        if ( Vec_PtrSize(vTokens) - nSize != nSize - 2 )
            return 0;
        Vec_PtrForEachEntryStart( char *, vTokens, pName, k, nSize )
            Vec_PtrWriteEntry( vTokens, k - nSize + 2, pName );
        Vec_PtrShrink( vTokens, nSize );
Alan Mishchenko committed
601
    }
602
    else
Alan Mishchenko committed
603
    {
604
        if ( i != Mio_GateReadPinNum(pGate) ) // expect the correct order of input pins in the network with twin gates
605 606
            return 0;
        // check the last two entries
607
        if ( nSize - 3 == Mio_GateReadPinNum(pGate) ) // only one output is available
Alan Mishchenko committed
608
        {
609 610 611 612 613 614 615 616 617 618 619 620 621
            pNamePin = Mio_GateReadOutName(pGate);
            Length = strlen(pNamePin);
            pName = (char *)Vec_PtrEntry(vTokens, nSize - 1);
            if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) // the last entry is pGate
            {
                Vec_PtrPush( vTokens, NULL );
                return 1;
            }
            pNamePin = Mio_GateReadOutName(pTwin);
            Length = strlen(pNamePin);
            pName = (char *)Vec_PtrEntry(vTokens, nSize - 1);
            if ( !strncmp( pNamePin, pName, Length ) && pName[Length] == '=' ) // the last entry is pTwin
            {
622
                pName = (char *)Vec_PtrPop( vTokens );
623 624 625 626 627
                Vec_PtrPush( vTokens, NULL );
                Vec_PtrPush( vTokens, pName );
                return 1;
            }
            return 0;
Alan Mishchenko committed
628
        }
629
        if ( nSize - 4 == Mio_GateReadPinNum(pGate) ) // two outputs are available
630 631 632 633 634 635 636 637 638 639 640 641 642 643
        {
            pNamePin = Mio_GateReadOutName(pGate);
            Length = strlen(pNamePin);
            pName = (char *)Vec_PtrEntry(vTokens, nSize - 2);
            if ( !(!strncmp( pNamePin, pName, Length ) && pName[Length] == '=') )
                return 0;
            pNamePin = Mio_GateReadOutName(pTwin);
            Length = strlen(pNamePin);
            pName = (char *)Vec_PtrEntry(vTokens, nSize - 1);
            if ( !(!strncmp( pNamePin, pName, Length ) && pName[Length] == '=') )
                return 0;
            return 1;
        }
        assert( 0 );
Alan Mishchenko committed
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
    }
    return 1;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
659 660 661 662 663 664 665 666 667
int Io_ReadBlifNetworkGate( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    Mio_Library_t * pGenlib; 
    Mio_Gate_t * pGate;
    Abc_Obj_t * pNode;
    char ** ppNames;
    int i, nNames;

    // check that the library is available
668
    pGenlib = (Mio_Library_t *)Abc_FrameReadLibGen();
Alan Mishchenko committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
    if ( pGenlib == NULL )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "The current library is not available." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }

    // create a new node and add it to the network
    if ( vTokens->nSize < 2 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "The .gate line has less than two tokens." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }

    // get the gate
687
    pGate = Mio_LibraryReadGateByName( pGenlib, (char *)vTokens->pArray[1], NULL );
Alan Mishchenko committed
688 689 690
    if ( pGate == NULL )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
Alan Mishchenko committed
691
        sprintf( p->sError, "Cannot find gate \"%s\" in the library.", (char*)vTokens->pArray[1] );
Alan Mishchenko committed
692 693 694 695 696
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }

    // if this is the first line with gate, update the network type
Alan Mishchenko committed
697
    if ( Abc_NtkNodeNum(p->pNtkCur) == 0 )
Alan Mishchenko committed
698
    {
Alan Mishchenko committed
699 700
        assert( p->pNtkCur->ntkFunc == ABC_FUNC_SOP );
        p->pNtkCur->ntkFunc = ABC_FUNC_MAP;
701
        Mem_FlexStop( (Mem_Flex_t *)p->pNtkCur->pManFunc, 0 );
Alan Mishchenko committed
702
        p->pNtkCur->pManFunc = pGenlib;
Alan Mishchenko committed
703 704
    }

Alan Mishchenko committed
705
    // reorder the formal inputs to be in the same order as in the gate
706
    if ( !Io_ReadBlifReorderFormalNames( vTokens, pGate, Mio_GateReadTwin(pGate) ) )
Alan Mishchenko committed
707 708 709 710 711 712 713 714
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Mismatch in the fanins of gate \"%s\".", (char*)vTokens->pArray[1] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }


Alan Mishchenko committed
715 716 717
    // remove the formal parameter names
    for ( i = 2; i < vTokens->nSize; i++ )
    {
718
        vTokens->pArray[i] = Io_ReadBlifCleanName( (char *)vTokens->pArray[i] );
Alan Mishchenko committed
719 720 721 722 723 724 725 726 727 728
        if ( vTokens->pArray[i] == NULL )
        {
            p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
            sprintf( p->sError, "Invalid gate input assignment." );
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
    }

    // create the node
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751
    if ( Mio_GateReadTwin(pGate) == NULL )
    {
        nNames  = vTokens->nSize - 3;
        ppNames = (char **)vTokens->pArray + 2;
        pNode   = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames );
        Abc_ObjSetData( pNode, pGate );
    }
    else
    {
        nNames  = vTokens->nSize - 4;
        ppNames = (char **)vTokens->pArray + 2;
        assert( ppNames[nNames] != NULL || ppNames[nNames+1] != NULL );
        if ( ppNames[nNames] )
        {
            pNode   = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames], ppNames, nNames );
            Abc_ObjSetData( pNode, pGate );
        }
        if ( ppNames[nNames+1] )
        {
            pNode   = Io_ReadCreateNode( p->pNtkCur, ppNames[nNames+1], ppNames, nNames );
            Abc_ObjSetData( pNode, Mio_GateReadTwin(pGate) );
        }
    }
Alan Mishchenko committed
752 753 754
    return 0;
}

Alan Mishchenko committed
755 756 757 758 759 760
/**Function*************************************************************

  Synopsis    [Creates a multi-input multi-output box in the hierarchical design.]

  Description []
               
Alan Mishchenko committed
761
  SideEffects [] 
Alan Mishchenko committed
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkSubcircuit( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    Abc_Obj_t * pBox;
    Vec_Ptr_t * vNames;
    char * pName;
    int i;

    // create a new node and add it to the network
    if ( vTokens->nSize < 3 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "The .subcircuit line has less than three tokens." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }

    // store the names of formal/actual inputs/outputs of the box
    vNames = Vec_PtrAlloc( 10 );
784
    Vec_PtrForEachEntryStart( char *, vTokens, pName, i, 1 )
Alan Mishchenko committed
785 786 787 788 789 790 791 792
//        Vec_PtrPush( vNames, Abc_NtkRegisterName(p->pNtkCur, pName) );
        Vec_PtrPush( vNames, Extra_UtilStrsav(pName) );  // memory leak!!!

    // create a new box and add it to the network
    pBox = Abc_NtkCreateBlackbox( p->pNtkCur );
    // set the pointer to the node names
    Abc_ObjSetData( pBox, vNames );
    // remember the line of the file
793
    pBox->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)Extra_FileReaderGetLineNumber(p->pReader, 0);
Alan Mishchenko committed
794 795
    return 0;
}
Alan Mishchenko committed
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
char * Io_ReadBlifCleanName( char * pName )
{
    int i, Length;
    Length = strlen(pName);
    for ( i = 0; i < Length; i++ )
        if ( pName[i] == '=' )
            return pName + i + 1;
    return NULL;
}
Alan Mishchenko committed
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    Abc_Obj_t * pNet;
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;
834
 
Alan Mishchenko committed
835
    // make sure this is indeed the .inputs line
836
    assert( strncmp( (char *)vTokens->pArray[0], ".input_arrival", 14 ) == 0 );
Alan Mishchenko committed
837 838 839 840 841 842 843
    if ( vTokens->nSize != 4 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .input_arrival line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
844
    pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] );
Alan Mishchenko committed
845 846 847
    if ( pNet == NULL )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
Alan Mishchenko committed
848
        sprintf( p->sError, "Cannot find object corresponding to %s on .input_arrival line.", (char*)vTokens->pArray[1] );
Alan Mishchenko committed
849 850 851
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
852 853
    TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 );
Alan Mishchenko committed
854 855 856
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
Alan Mishchenko committed
857
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_arrival line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] );
Alan Mishchenko committed
858 859 860 861
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
Alan Mishchenko committed
862
    Abc_NtkTimeSetArrival( p->pNtkCur, Abc_ObjFanin0(pNet)->Id, (float)TimeRise, (float)TimeFall );
Alan Mishchenko committed
863 864 865 866 867 868 869 870 871 872 873 874 875 876
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
int Io_ReadBlifNetworkOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    Abc_Obj_t * pNet;
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;
 
    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".output_required", 16 ) == 0 );
    if ( vTokens->nSize != 4 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .output_required line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] );
    if ( pNet == NULL )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Cannot find object corresponding to %s on .output_required line.", (char*)vTokens->pArray[1] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 );
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .output_required line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
    Abc_NtkTimeSetRequired( p->pNtkCur, Abc_ObjFanout0(pNet)->Id, (float)TimeRise, (float)TimeFall );
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
925 926 927 928 929 930
int Io_ReadBlifNetworkDefaultInputArrival( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;

    // make sure this is indeed the .inputs line
931
    assert( strncmp( (char *)vTokens->pArray[0], ".default_input_arrival", 23 ) == 0 );
Alan Mishchenko committed
932 933 934 935 936 937 938
    if ( vTokens->nSize != 3 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .default_input_arrival line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
939 940
    TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 );
Alan Mishchenko committed
941 942 943
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
Alan Mishchenko committed
944
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_arrival line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] );
Alan Mishchenko committed
945 946 947 948
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
Alan Mishchenko committed
949 950 951 952 953 954
    Abc_NtkTimeSetDefaultArrival( p->pNtkCur, (float)TimeRise, (float)TimeFall );
    return 0;
}

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

955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkDefaultOutputRequired( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;

    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".default_output_required", 25 ) == 0 );
    if ( vTokens->nSize != 3 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .default_output_required line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 );
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_output_required line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
    Abc_NtkTimeSetDefaultRequired( p->pNtkCur, (float)TimeRise, (float)TimeFall );
    return 0;
}

992 993 994 995 996 997 998 999 1000 1001 1002 1003

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1004 1005 1006 1007 1008 1009 1010 1011 1012
int Io_ReadFindCiId( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
{
    Abc_Obj_t * pTemp;
    int i;
    Abc_NtkForEachCi( pNtk, pTemp, i )
        if ( pTemp == pObj )
            return i;
    return -1;
}
1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045
int Io_ReadBlifNetworkInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    Abc_Obj_t * pNet;
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;
 
    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".input_drive", 12 ) == 0 );
    if ( vTokens->nSize != 4 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .input_drive line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] );
    if ( pNet == NULL )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Cannot find object corresponding to %s on .input_drive line.", (char*)vTokens->pArray[1] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 );
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .input_drive line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
1046
    Abc_NtkTimeSetInputDrive( p->pNtkCur, Io_ReadFindCiId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanin0(pNet)->Id)), (float)TimeRise, (float)TimeFall );
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
1061 1062 1063 1064 1065 1066 1067 1068 1069
int Io_ReadFindCoId( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
{
    Abc_Obj_t * pTemp;
    int i;
    Abc_NtkForEachPo( pNtk, pTemp, i )
        if ( pTemp == pObj )
            return i;
    return -1;
}
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
int Io_ReadBlifNetworkOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    Abc_Obj_t * pNet;
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;
 
    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".output_load", 12 ) == 0 );
    if ( vTokens->nSize != 4 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .output_load line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    pNet = Abc_NtkFindNet( p->pNtkCur, (char *)vTokens->pArray[1] );
    if ( pNet == NULL )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Cannot find object corresponding to %s on .output_load line.", (char*)vTokens->pArray[1] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    TimeRise = strtod( (char *)vTokens->pArray[2], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[3], &pFoo2 );
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .output_load line.", (char*)vTokens->pArray[2], (char*)vTokens->pArray[3] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
1103
    Abc_NtkTimeSetOutputLoad( p->pNtkCur, Io_ReadFindCoId(p->pNtkCur, Abc_NtkObj(p->pNtkCur, Abc_ObjFanout0(pNet)->Id)), (float)TimeRise, (float)TimeFall );
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkDefaultInputDrive( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;

    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".default_input_drive", 21 ) == 0 );
    if ( vTokens->nSize != 3 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .default_input_drive line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 );
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_input_drive line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
    Abc_NtkTimeSetDefaultInputDrive( p->pNtkCur, (float)TimeRise, (float)TimeFall );
    return 0;
}

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

  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkDefaultOutputLoad( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    char * pFoo1, * pFoo2;
    double TimeRise, TimeFall;

    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".default_output_load", 21 ) == 0 );
    if ( vTokens->nSize != 3 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments on .default_output_load line." );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    TimeRise = strtod( (char *)vTokens->pArray[1], &pFoo1 );
    TimeFall = strtod( (char *)vTokens->pArray[2], &pFoo2 );
    if ( *pFoo1 != '\0' || *pFoo2 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Bad value (%s %s) for rise or fall time on .default_output_load line.", (char*)vTokens->pArray[1], (char*)vTokens->pArray[2] );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
    Abc_NtkTimeSetDefaultOutputLoad( p->pNtkCur, (float)TimeRise, (float)TimeFall );
    return 0;
}

1185 1186
/**Function*************************************************************

1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
  Synopsis    []

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkAndGateDelay( Io_ReadBlif_t * p, Vec_Ptr_t * vTokens )
{
    char * pFoo1;
    double AndGateDelay;

    // make sure this is indeed the .inputs line
    assert( strncmp( (char *)vTokens->pArray[0], ".and_gate_delay", 25 ) == 0 );
    if ( vTokens->nSize != 2 )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
        sprintf( p->sError, "Wrong number of arguments (%d) on .and_gate_delay line (should be 1).", vTokens->nSize-1 );
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    AndGateDelay = strtod( (char *)vTokens->pArray[1], &pFoo1 );
    if ( *pFoo1 != '\0' )
    {
        p->LineCur = Extra_FileReaderGetLineNumber(p->pReader, 0);
1214
        sprintf( p->sError, "Bad value (%s) for AND gate delay in on .and_gate_delay line line.", (char*)vTokens->pArray[1] );
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }
    // set the arrival time
    p->pNtkCur->AndGateDelay = (float)AndGateDelay;
    return 0;
}

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

Alan Mishchenko committed
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
  Synopsis    [Prints the error message including the file name and line number.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Io_ReadBlifPrintErrorMessage( Io_ReadBlif_t * p )
{
    p->fError = 1;
    if ( p->LineCur == 0 ) // the line number is not given
        fprintf( p->Output, "%s: %s\n", p->pFileName, p->sError );
    else // print the error message with the line number
        fprintf( p->Output, "%s (line %d): %s\n", p->pFileName, p->LineCur, p->sError );
}

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

  Synopsis    [Gets the tokens taking into account the line breaks.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Vec_Ptr_t * Io_ReadBlifGetTokens( Io_ReadBlif_t * p )
{
    Vec_Ptr_t * vTokens;
    char * pLastToken;
    int i;

    // get rid of the old tokens
    if ( p->vNewTokens->nSize > 0 )
    {
        for ( i = 0; i < p->vNewTokens->nSize; i++ )
Alan Mishchenko committed
1264
            ABC_FREE( p->vNewTokens->pArray[i] );
Alan Mishchenko committed
1265 1266 1267 1268
        p->vNewTokens->nSize = 0;
    }

    // get the new tokens
1269
    vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p->pReader);
Alan Mishchenko committed
1270 1271 1272 1273
    if ( vTokens == NULL )
        return vTokens;

    // check if there is a transfer to another line
1274
    pLastToken = (char *)vTokens->pArray[vTokens->nSize - 1];
Alan Mishchenko committed
1275 1276 1277 1278 1279 1280 1281 1282 1283
    if ( pLastToken[ strlen(pLastToken)-1 ] != '\\' )
        return vTokens;

    // remove the slash
    pLastToken[ strlen(pLastToken)-1 ] = 0;
    if ( pLastToken[0] == 0 )
        vTokens->nSize--;
    // load them into the new array
    for ( i = 0; i < vTokens->nSize; i++ )
1284
        Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav((char *)vTokens->pArray[i]) );
Alan Mishchenko committed
1285 1286 1287 1288 1289

    // load as long as there is the line break
    while ( 1 )
    {
        // get the new tokens
1290
        vTokens = (Vec_Ptr_t *)Extra_FileReaderGetTokens(p->pReader);
Alan Mishchenko committed
1291 1292 1293
        if ( vTokens->nSize == 0 )
            return p->vNewTokens;
        // check if there is a transfer to another line
1294
        pLastToken = (char *)vTokens->pArray[vTokens->nSize - 1];
Alan Mishchenko committed
1295 1296 1297 1298 1299 1300 1301 1302
        if ( pLastToken[ strlen(pLastToken)-1 ] == '\\' )
        {
            // remove the slash
            pLastToken[ strlen(pLastToken)-1 ] = 0;
            if ( pLastToken[0] == 0 )
                vTokens->nSize--;
            // load them into the new array
            for ( i = 0; i < vTokens->nSize; i++ )
1303
                Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav((char *)vTokens->pArray[i]) );
Alan Mishchenko committed
1304 1305 1306 1307
            continue;
        }
        // otherwise, load them and break
        for ( i = 0; i < vTokens->nSize; i++ )
1308
            Vec_PtrPush( p->vNewTokens, Extra_UtilStrsav((char *)vTokens->pArray[i]) );
Alan Mishchenko committed
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336
        break;
    }
    return p->vNewTokens;
}

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

  Synopsis    [Starts the reading data structure.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Io_ReadBlif_t * Io_ReadBlifFile( char * pFileName )
{
    Extra_FileReader_t * pReader;
    Io_ReadBlif_t * p;

    // start the reader
    pReader = Extra_FileReaderAlloc( pFileName, "#", "\n\r", " \t" );

    if ( pReader == NULL )
        return NULL;

    // start the reading data structure
Alan Mishchenko committed
1337
    p = ABC_ALLOC( Io_ReadBlif_t, 1 );
Alan Mishchenko committed
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
    memset( p, 0, sizeof(Io_ReadBlif_t) );
    p->pFileName  = pFileName;
    p->pReader    = pReader;
    p->Output     = stdout;
    p->vNewTokens = Vec_PtrAlloc( 100 );
    p->vCubes     = Vec_StrAlloc( 100 );
    return p;
}

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

  Synopsis    [Frees the data structure.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
void Io_ReadBlifFree( Io_ReadBlif_t * p )
{
    Extra_FileReaderFree( p->pReader );
    Vec_PtrFree( p->vNewTokens );
    Vec_StrFree( p->vCubes );
Alan Mishchenko committed
1363
    ABC_FREE( p );
Alan Mishchenko committed
1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
}


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

  Synopsis    [Connect one box.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkConnectBoxesOneBox( Io_ReadBlif_t * p, Abc_Obj_t * pBox, stmm_table * tName2Model )
{
    Vec_Ptr_t * pNames;
    Abc_Ntk_t * pNtkModel;
    Abc_Obj_t * pObj, * pNet;
Alan Mishchenko committed
1383 1384
    char * pName = NULL, * pActual;
    int i, Length, Start = -1;
Alan Mishchenko committed
1385 1386

    // get the model for this box
1387 1388
    pNames = (Vec_Ptr_t *)pBox->pData;
    if ( !stmm_lookup( tName2Model, (char *)Vec_PtrEntry(pNames, 0), (char **)&pNtkModel ) )
Alan Mishchenko committed
1389
    {
Alan Mishchenko committed
1390
        p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1391
        sprintf( p->sError, "Cannot find the model for subcircuit %s.", (char*)Vec_PtrEntry(pNames, 0) );
Alan Mishchenko committed
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402
        Io_ReadBlifPrintErrorMessage( p );
        return 1;
    }

    // create the fanins of the box
    Abc_NtkForEachPi( pNtkModel, pObj, i )
        pObj->pCopy = NULL;
    if ( Abc_NtkPiNum(pNtkModel) == 0 )
        Start = 1;
    else
    {
1403
        Vec_PtrForEachEntryStart( char *, pNames, pName, i, 1 )
Alan Mishchenko committed
1404 1405 1406 1407
        {
            pActual = Io_ReadBlifCleanName(pName);
            if ( pActual == NULL )
            {
Alan Mishchenko committed
1408
                p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
                sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
                Io_ReadBlifPrintErrorMessage( p );
                return 1;
            }
            Length = pActual - pName - 1;
            pName[Length] = 0;
            // find the PI net with this name
            pObj = Abc_NtkFindNet( pNtkModel, pName );
            if ( pObj == NULL )
            {
Alan Mishchenko committed
1419
                p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1420
                sprintf( p->sError, "Cannot find formal input \"%s\" as an PI of model \"%s\".", pName, (char*)Vec_PtrEntry(pNames, 0) );
Alan Mishchenko committed
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
                Io_ReadBlifPrintErrorMessage( p );
                return 1;
            }
            // get the PI
            pObj = Abc_ObjFanin0(pObj);
            // quit if this is not a PI net
            if ( !Abc_ObjIsPi(pObj) )
            {
                pName[Length] = '=';
                Start = i;
                break;
            }
            // remember the actual name in the net
            if ( pObj->pCopy != NULL )
            {
Alan Mishchenko committed
1436
                p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1437 1438 1439 1440
                sprintf( p->sError, "Formal input \"%s\" is used more than once.", pName );
                Io_ReadBlifPrintErrorMessage( p );
                return 1;
            }
1441
            pObj->pCopy = (Abc_Obj_t *)pActual;
Alan Mishchenko committed
1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452
            // quit if we processed all PIs
            if ( i == Abc_NtkPiNum(pNtkModel) )
            {
                Start = i+1;
                break;
            }
        }
    }
    // create the fanins of the box
    Abc_NtkForEachPi( pNtkModel, pObj, i )
    {
1453
        pActual = (char *)pObj->pCopy;
Alan Mishchenko committed
1454 1455
        if ( pActual == NULL )
        {
Alan Mishchenko committed
1456
            p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1457
            sprintf( p->sError, "Formal input \"%s\" of model %s is not driven.", pName, (char*)Vec_PtrEntry(pNames, 0) );
Alan Mishchenko committed
1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
        pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
        Abc_ObjAddFanin( pBox, pNet );
    }
    Abc_NtkForEachPi( pNtkModel, pObj, i )
        pObj->pCopy = NULL;

    // create the fanouts of the box
    Abc_NtkForEachPo( pNtkModel, pObj, i )
        pObj->pCopy = NULL;
1470
    Vec_PtrForEachEntryStart( char *, pNames, pName, i, Start )
Alan Mishchenko committed
1471 1472 1473 1474
    {
        pActual = Io_ReadBlifCleanName(pName);
        if ( pActual == NULL )
        {
Alan Mishchenko committed
1475
            p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1476 1477 1478 1479 1480 1481 1482 1483 1484 1485
            sprintf( p->sError, "Cannot parse formal/actual name pair \"%s\".", pName );
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
        Length = pActual - pName - 1;
        pName[Length] = 0;
        // find the PO net with this name
        pObj = Abc_NtkFindNet( pNtkModel, pName );
        if ( pObj == NULL )
        {
Alan Mishchenko committed
1486
            p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1487
            sprintf( p->sError, "Cannot find formal output \"%s\" as an PO of model \"%s\".", pName, (char*)Vec_PtrEntry(pNames, 0) );
Alan Mishchenko committed
1488 1489 1490 1491 1492 1493 1494
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
        // get the PO
        pObj = Abc_ObjFanout0(pObj);
        if ( pObj->pCopy != NULL )
        {
Alan Mishchenko committed
1495
            p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1496 1497 1498 1499
            sprintf( p->sError, "Formal output \"%s\" is used more than once.", pName );
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
1500
        pObj->pCopy = (Abc_Obj_t *)pActual;
Alan Mishchenko committed
1501 1502 1503 1504
    }
    // create the fanouts of the box
    Abc_NtkForEachPo( pNtkModel, pObj, i )
    {
1505
        pActual = (char *)pObj->pCopy;
Alan Mishchenko committed
1506 1507
        if ( pActual == NULL )
        {
Alan Mishchenko committed
1508
            p->LineCur = (int)(ABC_PTRINT_T)pBox->pCopy;
Alan Mishchenko committed
1509
            sprintf( p->sError, "Formal output \"%s\" of model %s is not driven.", pName, (char*)Vec_PtrEntry(pNames, 0) );
Alan Mishchenko committed
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519
            Io_ReadBlifPrintErrorMessage( p );
            return 1;
        }
        pNet = Abc_NtkFindOrCreateNet( pBox->pNtk, pActual );
        Abc_ObjAddFanin( pNet, pBox );
    }
    Abc_NtkForEachPo( pNtkModel, pObj, i )
        pObj->pCopy = NULL;

    // remove the array of names, assign the pointer to the model
1520
    Vec_PtrForEachEntry( char *, (Vec_Ptr_t *)pBox->pData, pName, i )
Alan Mishchenko committed
1521
        ABC_FREE( pName );
1522
    Vec_PtrFree( (Vec_Ptr_t *)pBox->pData );
Alan Mishchenko committed
1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574
    pBox->pData = pNtkModel;
    return 0;
}

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

  Synopsis    [Connect the boxes in the hierarchy of networks.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkConnectBoxesOne( Io_ReadBlif_t * p, Abc_Ntk_t * pNtk, stmm_table * tName2Model )
{
    Abc_Obj_t * pBox;
    int i;
    // go through the boxes
    Abc_NtkForEachBlackbox( pNtk, pBox, i )
        if ( Io_ReadBlifNetworkConnectBoxesOneBox( p, pBox, tName2Model ) )
            return 1;
    Abc_NtkFinalizeRead( pNtk );
    return 0;
}

#if 0

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

  Synopsis    [Connect the boxes in the hierarchy of networks.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
int Io_ReadBlifNetworkConnectBoxes( Io_ReadBlif_t * p, Abc_Ntk_t * pNtkMaster )
{
    stmm_generator * gen;
    Abc_Ntk_t * pNtk;
    char * pName;
    // connect the master network
    if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtkMaster, pNtkMaster->tName2Model ) )
        return 1;
    // connect other networks
    stmm_foreach_item( pNtkMaster->tName2Model, gen, &pName, (char **)&pNtk )
        if ( Io_ReadBlifNetworkConnectBoxesOne( p, pNtk, pNtkMaster->tName2Model ) )
            return 1;
Alan Mishchenko committed
1575 1576
    return 0;
}
Alan Mishchenko committed
1577

Alan Mishchenko committed
1578
#endif
Alan Mishchenko committed
1579

Alan Mishchenko committed
1580 1581 1582 1583 1584
////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


1585 1586
ABC_NAMESPACE_IMPL_END