ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
sfmArea.c
Go to the documentation of this file.
1
20
21#include "sfmInt.h"
22#include "map/mio/mio.h"
23#include "misc/util/utilTruth.h"
24#include "misc/util/utilNam.h"
25#include "map/scl/sclLib.h"
26#include "map/scl/sclCon.h"
27#include "opt/dau/dau.h"
28
30
31
35
39
52{
53 Vec_Int_t * vInfo = Vec_IntAlloc( 1000 );
54 word iBestArea, tCur, iThis;
55 int * pPerm[7], nPerms[7], Perm[7], * Perm1, * Perm2;
56 int iBestCell, iBestPerm, iBestDiff;
57 int i, k, n, v, p, Count = 0;
58 int iGate1 = -1, iGate2 = -1;
59
60 for ( i = 1; i <= 6; i++ )
61 pPerm[i] = Extra_PermSchedule( i );
62 for ( i = 1; i <= 6; i++ )
63 nPerms[i] = Extra_Factorial( i );
64
65 for ( i = 2; i < nCells; i++ )
66 {
67 int nFanins = pCells[i].nFanins;
68 for ( n = 0; n <= nFanins; n++ )
69 {
70 // get the truth table
71 iThis = (n == nFanins) ? ~pCells[i].uTruth : Abc_Tt6Flip(pCells[i].uTruth, n);
72 // init the comparison
73 iBestArea = ~((word)0);
74 iBestCell = iBestPerm = iBestDiff = -1;
75 // iterate through cells
76 for ( k = 2; k < nCells; k++ )
77 {
78 if ( nFanins != (int)pCells[k].nFanins )
79 continue;
80 if ( i != k && pCells[i].uTruth == pCells[k].uTruth )
81 {
82 iGate1 = i;
83 iGate2 = k;
84 Count++;
85 continue;
86 }
87 // set unit permutation
88 for ( v = 0; v < nFanins; v++ )
89 Perm[v] = v;
90 // go through all permutation of Cell[k]
91 tCur = pCells[k].uTruth;
92 for ( p = 0; p < nPerms[nFanins]; p++ )
93 {
94 if ( iThis == tCur && iBestArea > pCells[k].AreaW )
95 {
96 iBestArea = pCells[k].AreaW;
97 iBestCell = k;
98 iBestPerm = 0;
99 for ( v = 0; v < nFanins; v++ )
100 iBestPerm |= (v << (Perm[v] << 2));
101 iBestDiff = (pCells[i].AreaW >= pCells[k].AreaW) ? (int)(pCells[i].AreaW - pCells[k].AreaW) : -(int)(pCells[k].AreaW - pCells[i].AreaW);
102 }
103 if ( nPerms[nFanins] == 1 )
104 continue;
105 // update
106 tCur = Abc_Tt6SwapAdjacent( tCur, pPerm[nFanins][p] );
107 Perm1 = Perm + pPerm[nFanins][p];
108 Perm2 = Perm1 + 1;
109 ABC_SWAP( int, *Perm1, *Perm2 );
110 }
111 assert( tCur == pCells[k].uTruth );
112 }
113 Vec_IntPushThree( vInfo, iBestCell, iBestPerm, iBestDiff );
114 }
115 }
116
117 for ( i = 1; i <= 6; i++ )
118 ABC_FREE( pPerm[i] );
119 if ( Count )
120 printf( "In this library, %d cell pairs have equal functions (for example, %s and %s).\n", Count/2, pCells[iGate1].pName, pCells[iGate2].pName );
121 return vInfo;
122}
124{
125 int i, Index = 0;
126 Vec_Int_t * vFirst = Vec_IntStartFull( 2 );
127 for ( i = 2; i < nCells; i++ )
128 {
129 Vec_IntPush( vFirst, Index );
130 Index += 3 * (pCells[i].nFanins + 1);
131 }
132 assert( nCells == Vec_IntSize(vFirst) );
133 return vFirst;
134}
135int Abc_NtkPrecomputePrint( Mio_Cell2_t * pCells, int nCells, Vec_Int_t * vInfo )
136{
137 int i, n, v, Index = 0, nRecUsed = 0;
138 for ( i = 2; i < nCells; i++ )
139 {
140 int nFanins = pCells[i].nFanins;
141 printf( "%3d : %8s Fanins = %d ", i, pCells[i].pName, nFanins );
142 Dau_DsdPrintFromTruth( &pCells[i].uTruth, nFanins );
143 for ( n = 0; n <= nFanins; n++, Index += 3 )
144 {
145 int iCellA = Vec_IntEntry( vInfo, Index+0 );
146 int iPerm = Vec_IntEntry( vInfo, Index+1 );
147 int Diff = Vec_IntEntry( vInfo, Index+2 );
148 if ( iCellA == -1 )
149 continue;
150 printf( "%d : {", n );
151 for ( v = 0; v < nFanins; v++ )
152 printf( " %d ", (iPerm >> (v << 2)) & 15 );
153 printf( "} Index = %d ", Index );
154
155 printf( "Gain = %6.2f ", Scl_Int2Flt(Diff) );
156 Dau_DsdPrintFromTruth( &pCells[iCellA].uTruth, pCells[iCellA].nFanins );
157 nRecUsed++;
158 }
159 }
160 return nRecUsed;
161}
162
164{
165 int nCells;
166 Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
167 Vec_Int_t * vInfo = Abc_NtkPrecomputeCellPairs( pCells, nCells );
168 int nRecUsed = Abc_NtkPrecomputePrint( pCells, nCells, vInfo );
169 // iterate through the cells
170 Vec_Int_t * vFirst = Abc_NtkPrecomputeFirsts( pCells, nCells );
171 printf( "Used records = %d. All records = %d.\n", nRecUsed, Vec_IntSize(vInfo)/3 - nRecUsed );
172 assert( nCells == Vec_IntSize(vFirst) );
173 Vec_IntFree( vFirst );
174 Vec_IntFree( vInfo );
175 ABC_FREE( pCells );
176}
177
179{
180 Abc_Obj_t * pThis;
181 int i;
182 Abc_ObjForEachFanout( pNode, pThis, i )
183 if ( Abc_NodeFindFanin(pThis, pFanin) >= 0 )
184 return i;
185 return -1;
186}
187
200{
201 int * pArray = pObj->vFanins.pArray;
202 int i, k, Limit = Abc_ObjFaninNum(pObj);
203 for ( i = 0; i < Limit; i++ )
204 for ( k = i+1; k < Limit; k++ )
205 if ( pArray[i] == pArray[k] )
206 return 1;
207 return 0;
208}
210{
211 int * pArray = pObj->vFanouts.pArray;
212 int i, k, Limit = Abc_ObjFanoutNum(pObj);
213 for ( i = 0; i < Limit; i++ )
214 for ( k = i+1; k < Limit; k++ )
215 if ( pArray[i] == pArray[k] )
216 return 1;
217 return 0;
218}
219int Abc_ObjChangeEval( Abc_Obj_t * pObj, Vec_Int_t * vInfo, Vec_Int_t * vFirst, int InvArea, int * pfUseInv )
220{
221 Abc_Obj_t * pNext;
222 //Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
223 int iFanCell, iNodeCell = Mio_GateReadCell( (Mio_Gate_t *)pObj->pData );
224 int * pFanInfo, * pNodeInfo = Vec_IntEntryP( vInfo, Vec_IntEntry(vFirst, iNodeCell) );
225 int i, fNeedInv = 0, Gain = 0, iFanin = Abc_ObjFaninNum(pObj), fUseInv = Abc_NodeIsInv(pObj);
226 assert( iFanin > 0 );
227 *pfUseInv = 0;
228 if ( pNodeInfo[3*iFanin] == -1 )
229 return 0;
230 if ( fUseInv )
231 Gain = InvArea;
232 else
233 Gain = pNodeInfo[3*iFanin+2];
234 Abc_ObjForEachFanout( pObj, pNext, i )
235 {
236 if ( fUseInv && Abc_NodeFindFanin(pNext, Abc_ObjFanin0(pObj)) >= 0 )
237 return 0;
238 if ( Abc_ObjHasDupFanins(pNext) )
239 return 0;
240 if ( !Abc_ObjIsNode(pNext) || Abc_NodeIsBuf(pNext) )
241 {
242 fNeedInv = 1;
243 continue;
244 }
245 if ( Abc_NodeIsInv(pNext) )
246 {
247 if ( Abc_NodeCheckFanoutHasFanin(pNext, pObj) >= 0 )
248 return 0;
249 Gain += InvArea;
250 continue;
251 }
252 iFanCell = Mio_GateReadCell( (Mio_Gate_t *)pNext->pData );
253 pFanInfo = Vec_IntEntryP( vInfo, Vec_IntEntry(vFirst, iFanCell) );
254 iFanin = Abc_NodeFindFanin( pNext, pObj );
255 if ( pFanInfo[3*iFanin] == -1 )
256 {
257 fNeedInv = 1;
258 continue;
259 }
260 Gain += pFanInfo[3*iFanin+2];
261 }
262 if ( fNeedInv )
263 Gain -= InvArea;
264 *pfUseInv = fNeedInv;
265 return Gain;
266}
267void Abc_ObjChangeUpdate( Abc_Obj_t * pObj, int iFanin, Mio_Cell2_t * pCells, int * pNodeInfo, Vec_Int_t * vTemp )
268{
269 int v, Perm, iNodeCell = pNodeInfo[3*iFanin];
270 //Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
271 //Abc_ObjPrint( stdout, pObj );
272 //printf( "Replacing fanout %d with %s by %s with fanin %d.\n", Abc_ObjId(pObj), Mio_GateReadName(pGate), Mio_GateReadName((Mio_Gate_t *)pCells[iNodeCell].pMioGate), iFanin );
273 pObj->pData = (Mio_Gate_t *)pCells[iNodeCell].pMioGate;
274 Perm = pNodeInfo[3*iFanin+1];
275 Vec_IntClear( vTemp );
276 for ( v = 0; v < Abc_ObjFaninNum(pObj); v++ )
277 Vec_IntPush( vTemp, Abc_ObjFaninId(pObj, (Perm >> (v << 2)) & 15) );
278 Vec_IntClear( &pObj->vFanins );
279 Vec_IntAppend( &pObj->vFanins, vTemp );
280}
281void Abc_ObjChangePerform( Abc_Obj_t * pObj, Vec_Int_t * vInfo, Vec_Int_t * vFirst, int fUseInv, Vec_Int_t * vTemp, Vec_Ptr_t * vFanout, Vec_Ptr_t * vFanout2, Mio_Cell2_t * pCells )
282{
283 Abc_Obj_t * pNext, * pNext2, * pNodeInv = NULL;
284 int iFanCell, iNodeCell = Mio_GateReadCell( (Mio_Gate_t *)pObj->pData );
285 int * pFanInfo, * pNodeInfo = Vec_IntEntryP( vInfo, Vec_IntEntry(vFirst, iNodeCell) );
286 int i, k, iFanin = Abc_ObjFaninNum(pObj);
287 assert( iFanin > 0 && pNodeInfo[3*iFanin] != -1 );
288 // update the node
289 Abc_NodeCollectFanouts( pObj, vFanout );
290 if ( Abc_NodeIsInv(pObj) )
291 {
292 Abc_Obj_t * pFanin = Abc_ObjFanin0(pObj);
293 Vec_PtrForEachEntry( Abc_Obj_t *, vFanout, pNext, k )
294 Abc_ObjPatchFanin( pNext, pObj, pFanin );
295 assert( Abc_ObjFanoutNum(pObj) == 0 );
296 Abc_NtkDeleteObj(pObj);
297 pObj = pFanin;
298// assert( fUseInv == 0 );
299 }
300 else
301 Abc_ObjChangeUpdate( pObj, iFanin, pCells, pNodeInfo, vTemp );
302 // add inverter if needed
303 if ( fUseInv )
304 pNodeInv = Abc_NtkCreateNodeInv(pObj->pNtk, pObj);
305 // update the fanouts
306 Vec_PtrForEachEntry( Abc_Obj_t *, vFanout, pNext, i )
307 {
308 if ( !Abc_ObjIsNode(pNext) || Abc_NodeIsBuf(pNext) )
309 {
310 Abc_ObjPatchFanin( pNext, pObj, pNodeInv );
311 continue;
312 }
313 if ( Abc_NodeIsInv(pNext) )
314 {
315 Abc_NodeCollectFanouts( pNext, vFanout2 );
316 Vec_PtrForEachEntry( Abc_Obj_t *, vFanout2, pNext2, k )
317 Abc_ObjPatchFanin( pNext2, pNext, pObj );
318 assert( Abc_ObjFanoutNum(pNext) == 0 );
319 Abc_NtkDeleteObj(pNext);
320 continue;
321 }
322 iFanin = Abc_NodeFindFanin( pNext, pObj );
323 iFanCell = Mio_GateReadCell( (Mio_Gate_t *)pNext->pData );
324 pFanInfo = Vec_IntEntryP( vInfo, Vec_IntEntry(vFirst, iFanCell) );
325 if ( pFanInfo[3*iFanin] == -1 )
326 {
327 Abc_ObjPatchFanin( pNext, pObj, pNodeInv );
328 continue;
329 }
330 Abc_ObjChangeUpdate( pNext, iFanin, pCells, pFanInfo, vTemp );
331 }
332}
333void Abc_NtkChangePerform( Abc_Ntk_t * pNtk, int fVerbose )
334{
335 abctime clk = Abc_Clock();
336 int i, fNeedInv, nCells, Gain, GainAll = 0, Count = 0, CountInv = 0;
337 Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
338 Vec_Int_t * vInfo = Abc_NtkPrecomputeCellPairs( pCells, nCells );
339 Vec_Int_t * vFirst = Abc_NtkPrecomputeFirsts( pCells, nCells );
340
341 Vec_Ptr_t * vFanout = Vec_PtrAlloc( 100 );
342 Vec_Ptr_t * vFanout2 = Vec_PtrAlloc( 100 );
343 Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
344 Abc_Obj_t * pObj;
345 Abc_NtkForEachNode( pNtk, pObj, i )
346 {
347 if ( Abc_ObjFaninNum(pObj) < 2 && !Abc_NodeIsInv(pObj) )
348 continue;
349 if ( Abc_ObjHasDupFanouts(pObj) )
350 continue;
351 Gain = Abc_ObjChangeEval( pObj, vInfo, vFirst, (int)pCells[3].AreaW, &fNeedInv );
352 if ( Gain <= 0 )
353 continue;
354 //printf( "Obj %d\n", Abc_ObjId(pObj) );
355 Count++;
356 CountInv += Abc_NodeIsInv(pObj);
357 GainAll += Gain;
358 Abc_ObjChangePerform( pObj, vInfo, vFirst, fNeedInv, vTemp, vFanout, vFanout2, pCells );
359 }
360 Vec_PtrFree( vFanout2 );
361 Vec_PtrFree( vFanout );
362 Vec_IntFree( vTemp );
363
364 Vec_IntFree( vFirst );
365 Vec_IntFree( vInfo );
366 ABC_FREE( pCells );
367
368 if ( fVerbose )
369 printf( "Total gain in area = %6.2f after %d changes (including %d inverters). ", Scl_Int2Flt(GainAll), Count, CountInv );
370 if ( fVerbose )
371 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
372}
373
377
378
380
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
ABC_DLL void Abc_NtkDeleteObj(Abc_Obj_t *pObj)
Definition abcObj.c:170
ABC_DLL int Abc_NodeIsBuf(Abc_Obj_t *pNode)
Definition abcObj.c:948
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
ABC_DLL int Abc_NodeIsInv(Abc_Obj_t *pNode)
Definition abcObj.c:980
ABC_DLL void Abc_NodeCollectFanouts(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcUtil.c:1647
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeInv(Abc_Ntk_t *pNtk, Abc_Obj_t *pFanin)
Definition abcObj.c:674
ABC_DLL void Abc_ObjPatchFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFaninOld, Abc_Obj_t *pFaninNew)
Definition abcFanio.c:172
ABC_DLL int Abc_NodeFindFanin(Abc_Obj_t *pNode, Abc_Obj_t *pFanin)
Definition abcUtil.c:791
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition abc.h:464
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
void Dau_DsdPrintFromTruth(word *pTruth, int nVarsInit)
Definition dauDsd.c:1968
Cube * p
Definition exorList.c:222
int * Extra_PermSchedule(int n)
int Extra_Factorial(int n)
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
Mio_Cell2_t * Mio_CollectRootsNewDefault2(int nInputs, int *pnGates, int fVerbose)
Definition mioUtils.c:877
struct Mio_Cell2_t_ Mio_Cell2_t
Definition mio.h:57
struct Mio_GateStruct_t_ Mio_Gate_t
Definition mio.h:43
int Mio_GateReadCell(Mio_Gate_t *pGate)
Definition mioApi.c:184
Vec_Int_t * Abc_NtkPrecomputeFirsts(Mio_Cell2_t *pCells, int nCells)
Definition sfmArea.c:123
void Abc_NtkPrecomputeCellPairsTest()
Definition sfmArea.c:163
int Abc_ObjHasDupFanouts(Abc_Obj_t *pObj)
Definition sfmArea.c:209
void Abc_ObjChangeUpdate(Abc_Obj_t *pObj, int iFanin, Mio_Cell2_t *pCells, int *pNodeInfo, Vec_Int_t *vTemp)
Definition sfmArea.c:267
void Abc_ObjChangePerform(Abc_Obj_t *pObj, Vec_Int_t *vInfo, Vec_Int_t *vFirst, int fUseInv, Vec_Int_t *vTemp, Vec_Ptr_t *vFanout, Vec_Ptr_t *vFanout2, Mio_Cell2_t *pCells)
Definition sfmArea.c:281
int Abc_NtkPrecomputePrint(Mio_Cell2_t *pCells, int nCells, Vec_Int_t *vInfo)
Definition sfmArea.c:135
int Abc_ObjChangeEval(Abc_Obj_t *pObj, Vec_Int_t *vInfo, Vec_Int_t *vFirst, int InvArea, int *pfUseInv)
Definition sfmArea.c:219
int Abc_ObjHasDupFanins(Abc_Obj_t *pObj)
Definition sfmArea.c:199
int Abc_NodeCheckFanoutHasFanin(Abc_Obj_t *pNode, Abc_Obj_t *pFanin)
Definition sfmArea.c:178
ABC_NAMESPACE_IMPL_START Vec_Int_t * Abc_NtkPrecomputeCellPairs(Mio_Cell2_t *pCells, int nCells)
DECLARATIONS ///.
Definition sfmArea.c:51
void Abc_NtkChangePerform(Abc_Ntk_t *pNtk, int fVerbose)
Definition sfmArea.c:333
void * pData
Definition abc.h:145
Vec_Int_t vFanins
Definition abc.h:143
Abc_Ntk_t * pNtk
Definition abc.h:130
Vec_Int_t vFanouts
Definition abc.h:144
word uTruth
Definition mio.h:67
word AreaW
Definition mio.h:66
unsigned nFanins
Definition mio.h:64
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55