/**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 ABC__aig__bbl__bblif_h #define ABC__aig__bbl__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 /// ////////////////////////////////////////////////////////////////////////