1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
/**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 ///
////////////////////////////////////////////////////////////////////////
|