/**CFile****************************************************************

  FileName    [bblif.h]

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Binary BLIF representation for logic networks.]

  Synopsis    [External declarations.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - February 28, 2009.]

  Revision    [$Id: bblif.h,v 1.00 2009/02/28 00:00:00 alanmi Exp $]

***********************************************************************/
 
#ifndef __BBLIF_H__
#define __BBLIF_H__


/*
    This file (taken together with "bblif.c") implements a stand-alone 
    interface between ABC and an application that uses ABC. 
    
    The interface is designed to pass a combinational logic network 
    from the calling application to ABC using a binary BLIF format (BBLIF) 
    and return the network after synthesis/mapping/verification in ABC 
    back to the caller.

    The interface can do the following:
    (1) accept a combinational logic network via a set of APIs
    (2) write the logic network into a binary BLIF file readable by ABC
    (3) read a binary BLIF file with a mapped network produced by ABC
    (4) return the mapped network to the caller through a set of APIs

    It should be noted that the BBLIF interface can be used to pass
    the network from the calling application into ABC without writing it
    into a file. In this case, ABC should be compiled as a library and
    linked to the calling application. The BBLIF manager can be given
    directly to the procedure Bbl_ManToAbc() to convert it into an AIG.
    Similarly, the resulting mapped network can be converted into
    BBLIF manager and passed back after the call to Bbl_ManFromAbc().

    Here these steps are described in more detail:

    (1) The BBLIF manager is allocated by calling Bbl_ManStart() and 
        deallocated by calling Bbl_ManStop(). 
    
        The combinational network is composed of three types of objects:
        (a) combinational inputs (CIs), (b) combinational outputs (COs), 
        (c) internal logic nodes represented using Sum-of-Products (SOPs)
        similar to the way logic nodes are represented in SIS. Sequential 
        elements (flops) are currently not supported.   A CI has no fanins. 
        A CO has exactly one fanin and no fanouts. Internal nodes can 
        have any number of fanins and fanouts. Only an internal node can 
        have a logic function.

        Before constructing the BBLIF manager, each object should be 
        assigned a unique non-negative (0-based) integer ID. The sequence
        of ID numbers may have gaps in it (for example, 0, 1, 2, 5, 6, etc)
        but care should be taken that the ID numbers do not grow too large
        because internally they are used to index the objects. So if 
        the largest given ID has value N, an array of 4*N bytes will be 
        allocated internally by the BBLIF manager. Obviously if N = 1M, 
        the array will use 4Mb, but if N = 100M, it will use 0.4Gb.

        This object ID (called also "the original ID of the object") is 
        given to Bbl_ManCreateObject(), which construct the BBLIF objects 
        and to the procedure Bbl_ManAddFanin(), which creates fanin/fanout
        relations between two objects.  The exact number of fanins of an
        object should be declared when calling Bbl_ManCreateObject(). 
        Later on, each node should be assigned as many fanins using 
        Bbl_ManAddFanin(). The order/number of fanins corresponds to the 
        order/number of variables in the SOP of the logic function of the 
        node. The declared and actual number of fanins should be the same.
        otherwise the interface will not function correctly. This is checked
        by the procedure Bbl_ManCheck(), which should be called when 
        constructing all objects and their fanins is finished.

        The SOP representation of the logic function should be given to
        every internal node. It is given as a C-string, showing the SOP
        as it would appear in a BLIF or PLA file. Each cube is composed
        of characters '0', '1', and '-', and ended by a seqence of three
        characters: space ' ', followed by '0' or '1' (depending on whether 
        on- or off-set is used), followed by the new line character '\n'. 
        For example, a two-input OR has the following SOP representation: 
        "1- 1\n-1 1\n", or equivalently, "00 0\n". The SOP for a constant 
        function with no fanins is represented as " 0\n" (constant 0) and
        " 1\n" (constant 1). SOP for a constant node with some fanins
        may also be represented. For example, constant 0 node with three 
        fanins will have SOP representation as follows: "--- 0\n".

        The objects can be added to the BBLIF manager in any order, but 
        by the time the fanin/fanout connections are created, corresponding 
        objects should be already created.

        The number of objects is limited by 2^31. The number of fanins
        of one object is restricted to 2^28. The SOP representation can 
        have arbitrary many products (cubes), as long as memory is enough
        to represent them in the C-string form, as described above.

    (2) To write the manager into a file, call procedure Bbl_ManDumpBinaryBlif().
        It is recommended to use files with extension ".bblif" because it
        will allow ABC to call the approapriate reader in command "read".

    (3) To read the network from file, call procedure Bbl_ManReadBinaryBlif().

    (4) It is assumed that ABC will return the network after mapping.
        This network will arrive in a BBLIF file, from which the BBLIF 
        manager is created by the call to Bbl_ManReadBinaryBlif(). The 
        following APIs are useful to extract the mapped network from the manager:
        
        Iterator Bbl_ManForEachObj() iterates through the pointers to the
        BBLIF objects, which are guaranteed to be in a topological order. 

        For each object, the following APIs can be used:
        Bbl_ObjIsInput() returns 1 if the object is a CI
        Bbl_ObjIsOutput() returns 1 if the object is a CO
        Bbl_ObjIsLut() returns 1 if the object is a logic node (lookup table)
        Bbl_ObjFaninNumber() returns the number of fanins of the node
        Bbl_ObjSop() returns the SOP representation of the node, as described above.

        A special attention should be given to the representation of object IDs
        after mapping. Recall that when the outgoing BBLIF network is constructed, 
        the IDs of objects are assigned by the calling application and given to 
        the BBLIF manager when procedure Bbl_ManCreateObject() is called.  
        We refer to these object IDs as "original IDs of the objects". 
        
        When the network has been given to ABC, mapped, and returned to the 
        calling application in the incoming BBLIF file, only CIs and COs are 
        guaranteed to preserve their "original IDs". Other objects may be created 
        during synthesis/mapping. The original IDs of these objects are set to -1. 

        The following two APIs are used to return the IDs of objects after mapping:
        Bbl_ObjId() returns the new ID (useful to construct network after mapping)
        Bbl_ObjIdOriginal() returns the original ID (or -1 if this is a new object).

        !!!***!!!
        Note: The original ID currently cannot be returned by Bbl_ObjIdOriginal().
        It is recommended to use the work-around described below.
        !!!***!!!

        The original ID is useful to map CIs/COs after mapping into CIs/COs before
        mapping. However, the order of CIs/COs after mapping in the incoming network 
        is the same as the order of their creation by the calling application 
        in the outgoing network. This allows for a workaround that does not have 
        the need for the original IDs.  We can simply iterate through the objects 
        after mapping, and create CIs and COs in the order of their appearance, 
        and this order is guaranteed to be the same as the order of their 
        construction by the calling application.

        It is also worth noting that currently the internal node names are not 
        preserved by ABC during synthesis. This may change in the future. and then 
        some of the internal nodes will preserve their IDs, which may allow the 
        calling application to reconstruct the names of some of the nodes after 
        synthesis/mapping in ABC using their original IDs whenever available.

        Finally, iterator Bbl_ObjForEachFanin() can be used to iterate through 
        the fanins of each mapped object. For CIs, there will be no fanins. 
        For COs, there will be exactly one fanin. For the internal nodes (LUTs)
        the number of fanins is the number of inputs of these nodes.

    A demo of using this interface is included at the bottom of file "bblif.c" in 
    procedure Bbl_ManSimpleDemo(). Additional examples can be found in the files
    "abc\src\base\io\ioReadBblif.c" and "abc\src\base\io\ioWriteBblif.c". These
    files illustrate how an ABC network is created from the BBLIF data manager 
    and how the data manager is created from the ABC network. 
    
    Note that only the files "bblif.h" and "bblif.c" are needed for interfacing
    the user's application with ABC, while other files should not be compiled 
    as part of the application code.

    Finally, a warning regarding endianness. The interface may not work 
    if the BBLIF file is produced on a machine whose engianness is different 
    from the machine, which is reading this file.
*/

////////////////////////////////////////////////////////////////////////
///                          INCLUDES                                ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                         PARAMETERS                               ///
////////////////////////////////////////////////////////////////////////



ABC_NAMESPACE_HEADER_START


#ifdef _WIN32
#define inline __inline
#endif

////////////////////////////////////////////////////////////////////////
///                         BASIC TYPES                              ///
////////////////////////////////////////////////////////////////////////

// object types
typedef enum { 
    BBL_OBJ_NONE,                // 0: non-existent object
    BBL_OBJ_CI,                  // 1: primary input
    BBL_OBJ_CO,                  // 2: primary output
    BBL_OBJ_NODE,                // 3: buffer node
    BBL_OBJ_VOID                 // 4: unused object
} Bbl_Type_t;

// data manager
typedef struct Bbl_Man_t_ Bbl_Man_t;

// data object
typedef struct Bbl_Obj_t_ Bbl_Obj_t;

////////////////////////////////////////////////////////////////////////
///                      MACRO DEFINITIONS                           ///
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
///                    FUNCTION DECLARATIONS                         ///
////////////////////////////////////////////////////////////////////////

// (1) creating the data manager in the application code
extern Bbl_Man_t * Bbl_ManStart( char * pName );
extern void        Bbl_ManCreateObject( Bbl_Man_t * p, Bbl_Type_t Type, int ObjId, int nFanins, char * pSop );
extern void        Bbl_ManAddFanin( Bbl_Man_t * p, int ObjId, int FaninId );
extern int         Bbl_ManCheck( Bbl_Man_t * p );
extern void        Bbl_ManPrintStats( Bbl_Man_t * p );
extern void        Bbl_ManStop( Bbl_Man_t * p );

// (2) writing the data manager into file
extern void        Bbl_ManDumpBinaryBlif( Bbl_Man_t * p, char * pFileName );

// (3) reading the data manager from file
extern Bbl_Man_t * Bbl_ManReadBinaryBlif( char * pFileName );

// (4) returning the mapped network after reading the data manaager from file
extern char *      Bbl_ManName( Bbl_Man_t * p );
extern int         Bbl_ObjIsInput( Bbl_Obj_t * p );
extern int         Bbl_ObjIsOutput( Bbl_Obj_t * p );
extern int         Bbl_ObjIsLut( Bbl_Obj_t * p );
extern int         Bbl_ObjId( Bbl_Obj_t * p );
extern int         Bbl_ObjIdOriginal( Bbl_Man_t * pMan, Bbl_Obj_t * p );
extern int         Bbl_ObjFaninNumber( Bbl_Obj_t * p );
extern char *      Bbl_ObjSop( Bbl_Man_t * pMan, Bbl_Obj_t * p );

// for the use in iterators only
extern Bbl_Obj_t * Bbl_ManObjFirst( Bbl_Man_t * p );
extern Bbl_Obj_t * Bbl_ManObjNext( Bbl_Man_t * p, Bbl_Obj_t * pObj );
extern Bbl_Obj_t * Bbl_ObjFaninFirst( Bbl_Obj_t * p );
extern Bbl_Obj_t * Bbl_ObjFaninNext( Bbl_Obj_t * p, Bbl_Obj_t * pPrev );

// iterator through the objects
#define Bbl_ManForEachObj( p, pObj )                \
    for ( pObj = Bbl_ManObjFirst(p); pObj; pObj = Bbl_ManObjNext(p, pObj) )
// iterator through the fanins fo the an object
#define Bbl_ObjForEachFanin( pObj, pFanin )         \
    for ( pFanin = Bbl_ObjFaninFirst(pObj); pFanin; pFanin = Bbl_ObjFaninNext(pObj, pFanin) )

// these additional procedures are provided to transform truth tables into SOPs, and vice versa
extern char *      Bbl_ManTruthToSop( unsigned * pTruth, int nVars );
extern unsigned *  Bbl_ManSopToTruth( char * pSop, int nVars );

// write text BLIF file for debugging
extern void        Bbl_ManDumpBlif( Bbl_Man_t * p, char * pFileName );

// a simple demo procedure
extern void        Bbl_ManSimpleDemo();




ABC_NAMESPACE_HEADER_END



#endif

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////

