ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcDetect.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22#include "misc/vec/vecHsh.h"
23#include "misc/util/utilNam.h"
24#include "sat/cnf/cnf.h"
25#include "sat/bsat/satStore.h"
26#include "map/mio/mio.h"
27#include "map/mio/exp.h"
28
30
34
50
54
66void Abc_NtkGenFaultList( Abc_Ntk_t * pNtk, char * pFileName, int fStuckAt )
67{
68 Mio_Library_t * pLib = (Mio_Library_t *)pNtk->pManFunc;
69 Mio_Gate_t * pGate;
70 Abc_Obj_t * pObj;
71 int i, Count = 1;
72 FILE * pFile = fopen( pFileName, "wb" );
73 if ( pFile == NULL )
74 {
75 printf( "Cannot open file \"%s\" for writing.\n", pFileName );
76 return;
77 }
78 assert( Abc_NtkIsMappedLogic(pNtk) );
79 Abc_NtkForEachNode( pNtk, pObj, i )
80 {
81 Mio_Gate_t * pGateObj = (Mio_Gate_t *)pObj->pData;
82 int nInputs = Mio_GateReadPinNum(pGateObj);
83 // add basic faults (SA0, SA1, NEG)
84 fprintf( pFile, "%d %s %s\n", Count, Abc_ObjName(pObj), "SA0" ), Count++;
85 fprintf( pFile, "%d %s %s\n", Count, Abc_ObjName(pObj), "SA1" ), Count++;
86 fprintf( pFile, "%d %s %s\n", Count, Abc_ObjName(pObj), "NEG" ), Count++;
87 if ( fStuckAt )
88 continue;
89 // add other faults, which correspond to changing the given gate
90 // by another gate with the same support-size from the same library
91 Mio_LibraryForEachGate( pLib, pGate )
92 if ( pGate != pGateObj && Mio_GateReadPinNum(pGate) == nInputs )
93 fprintf( pFile, "%d %s %s\n", Count, Abc_ObjName(pObj), Mio_GateReadName(pGate) ), Count++;
94 }
95 printf( "Generated fault list \"%s\" for network \"%s\" with %d nodes and %d %sfaults.\n",
96 pFileName, Abc_NtkName(pNtk), Abc_NtkNodeNum(pNtk), Count-1, fStuckAt ? "stuck-at ":"" );
97 fclose( pFile );
98}
99
111int Io_ReadFinTypeMapped( Mio_Library_t * pLib, char * pThis )
112{
113 Mio_Gate_t * pGate = Mio_LibraryReadGateByName( pLib, pThis, NULL );
114 if ( pGate == NULL )
115 {
116 printf( "Cannot find gate \"%s\" in the current library.\n", pThis );
117 return ABC_FIN_NONE;
118 }
119 return Mio_GateReadCell( pGate );
120}
121int Io_ReadFinType( char * pThis )
122{
123 if ( !strcmp(pThis, "SA0") ) return ABC_FIN_SA0;
124 if ( !strcmp(pThis, "SA1") ) return ABC_FIN_SA1;
125 if ( !strcmp(pThis, "NEG") ) return ABC_FIN_NEG;
126 if ( !strcmp(pThis, "RDOB_AND") ) return ABC_FIN_RDOB_AND;
127 if ( !strcmp(pThis, "RDOB_NAND") ) return ABC_FIN_RDOB_NAND;
128 if ( !strcmp(pThis, "RDOB_OR") ) return ABC_FIN_RDOB_OR;
129 if ( !strcmp(pThis, "RDOB_NOR") ) return ABC_FIN_RDOB_NOR;
130 if ( !strcmp(pThis, "RDOB_XOR") ) return ABC_FIN_RDOB_XOR;
131 if ( !strcmp(pThis, "RDOB_NXOR") ) return ABC_FIN_RDOB_NXOR;
132 if ( !strcmp(pThis, "RDOB_NOT") ) return ABC_FIN_RDOB_NOT;
133 if ( !strcmp(pThis, "RDOB_BUFF") ) return ABC_FIN_RDOB_BUFF;
134 return ABC_FIN_NONE;
135}
136char * Io_WriteFinType( int Type )
137{
138 if ( Type == ABC_FIN_SA0 ) return "SA0";
139 if ( Type == ABC_FIN_SA1 ) return "SA1";
140 if ( Type == ABC_FIN_NEG ) return "NEG";
141 if ( Type == ABC_FIN_RDOB_AND ) return "RDOB_AND" ;
142 if ( Type == ABC_FIN_RDOB_NAND ) return "RDOB_NAND";
143 if ( Type == ABC_FIN_RDOB_OR ) return "RDOB_OR" ;
144 if ( Type == ABC_FIN_RDOB_NOR ) return "RDOB_NOR" ;
145 if ( Type == ABC_FIN_RDOB_XOR ) return "RDOB_XOR" ;
146 if ( Type == ABC_FIN_RDOB_NXOR ) return "RDOB_NXOR";
147 if ( Type == ABC_FIN_RDOB_NOT ) return "RDOB_NOT" ;
148 if ( Type == ABC_FIN_RDOB_BUFF ) return "RDOB_BUFF";
149 return "Unknown";
150}
151
164Vec_Int_t * Io_ReadFins( Abc_Ntk_t * pNtk, char * pFileName, int fVerbose )
165{
166 Mio_Library_t * pLib = (Mio_Library_t *)pNtk->pManFunc;
167 char Buffer[1000];
168 Abc_Obj_t * pObj;
169 Abc_Nam_t * pNam;
170 Vec_Int_t * vMap;
171 Vec_Int_t * vPairs = NULL;
172 int i, Type, iObj, fFound, nLines = 1;
173 FILE * pFile = fopen( pFileName, "r" );
174 if ( pFile == NULL )
175 {
176 printf( "Cannot open input file \"%s\" for reading.\n", pFileName );
177 return NULL;
178 }
179 // map CI/node names into their IDs
180 pNam = Abc_NamStart( 1000, 10 );
181 vMap = Vec_IntAlloc( 1000 );
182 Vec_IntPush( vMap, -1 );
183 Abc_NtkForEachObj( pNtk, pObj, i )
184 {
185 if ( !Abc_ObjIsCi(pObj) && !Abc_ObjIsNode(pObj) )
186 continue;
187 Abc_NamStrFindOrAdd( pNam, Abc_ObjName(pObj), &fFound );
188 if ( fFound )
189 {
190 printf( "The same name \"%s\" appears twice among CIs and internal nodes.\n", Abc_ObjName(pObj) );
191 goto finish;
192 }
193 Vec_IntPush( vMap, Abc_ObjId(pObj) );
194 }
195 assert( Vec_IntSize(vMap) == Abc_NamObjNumMax(pNam) );
196 // read file lines
197 vPairs = Vec_IntAlloc( 1000 );
198 Vec_IntPushTwo( vPairs, -1, -1 );
199 while ( fgets(Buffer, 1000, pFile) != NULL )
200 {
201 // read line number
202 char * pToken = strtok( Buffer, " \n\r\t" );
203 if ( pToken == NULL )
204 break;
205 if ( nLines++ != atoi(pToken) )
206 {
207 printf( "Line numbers are not consecutive. Quitting.\n" );
208 Vec_IntFreeP( &vPairs );
209 goto finish;
210 }
211 // read object name and find its ID
212 pToken = strtok( NULL, " \n\r\t" );
213 iObj = Abc_NamStrFind( pNam, pToken );
214 if ( !iObj )
215 {
216 printf( "Cannot find object with name \"%s\".\n", pToken );
217 continue;
218 }
219 // read type
220 pToken = strtok( NULL, " \n\r\t" );
221 if ( Abc_NtkIsMappedLogic(pNtk) )
222 {
223 if ( !strcmp(pToken, "SA0") || !strcmp(pToken, "SA1") || !strcmp(pToken, "NEG") )
224 Type = Io_ReadFinType( pToken );
225 else
226 Type = Io_ReadFinTypeMapped( pLib, pToken );
227 }
228 else
229 Type = Io_ReadFinType( pToken );
230 if ( Type == ABC_FIN_NONE )
231 {
232 printf( "Cannot read type \"%s\" of object \"%s\".\n", pToken, Abc_ObjName(Abc_NtkObj(pNtk, iObj)) );
233 continue;
234 }
235 Vec_IntPushTwo( vPairs, Vec_IntEntry(vMap, iObj), Type );
236 }
237 assert( Vec_IntSize(vPairs) == 2 * nLines );
238 printf( "Finished reading %d lines from the fault list file \"%s\".\n", nLines - 1, pFileName );
239
240 // verify the reader by printing the results
241 if ( fVerbose )
242 Vec_IntForEachEntryDoubleStart( vPairs, iObj, Type, i, 2 )
243 printf( "%-10d%-10s%-10s\n", i/2, Abc_ObjName(Abc_NtkObj(pNtk, iObj)), Io_WriteFinType(Type) );
244
245finish:
246 Vec_IntFree( vMap );
247 Abc_NamDeref( pNam );
248 fclose( pFile );
249 return vPairs;
250}
251
252
265{
266 Vec_Ptr_t * vFanins, * vNodes;
267 Abc_Obj_t * pObj, * pFanin, * pReset, * pEnable, * pSignal;
268 Abc_Obj_t * pResetN, * pEnableN, * pAnd0, * pAnd1, * pMux;
269 int i, k, iStartPo, nPisOld = Abc_NtkPiNum(pNtk), nPosOld = Abc_NtkPoNum(pNtk);
270 // skip if there are no flops
271 if ( pNtk->nConstrs == 0 )
272 return;
273 assert( Abc_NtkPiNum(pNtk) >= pNtk->nConstrs );
274 assert( Abc_NtkPoNum(pNtk) >= pNtk->nConstrs * 4 );
275 // collect nodes
276 vNodes = Vec_PtrAlloc( Abc_NtkNodeNum(pNtk) );
277 Abc_NtkForEachNode( pNtk, pObj, i )
278 Vec_PtrPush( vNodes, pObj );
279 // duplicate PIs
280 vFanins = Vec_PtrAlloc( 2 );
281 Abc_NtkForEachPi( pNtk, pObj, i )
282 {
283 if ( i == nPisOld )
284 break;
285 if ( i < nPisOld - pNtk->nConstrs )
286 {
287 Abc_NtkDupObj( pNtk, pObj, 0 );
288 Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), "_frame1" );
289 continue;
290 }
291 // create flop input
292 iStartPo = nPosOld + 4 * (i - nPisOld);
293 pReset = Abc_ObjFanin0( Abc_NtkPo( pNtk, iStartPo + 1 ) );
294 pEnable = Abc_ObjFanin0( Abc_NtkPo( pNtk, iStartPo + 2 ) );
295 pSignal = Abc_ObjFanin0( Abc_NtkPo( pNtk, iStartPo + 3 ) );
296 pResetN = Abc_NtkCreateNodeInv( pNtk, pReset );
297 pEnableN = Abc_NtkCreateNodeInv( pNtk, pEnable );
298 Vec_PtrFillTwo( vFanins, 2, pEnableN, pObj );
299 pAnd0 = Abc_NtkCreateNodeAnd( pNtk, vFanins );
300 Vec_PtrFillTwo( vFanins, 2, pEnable, pSignal );
301 pAnd1 = Abc_NtkCreateNodeAnd( pNtk, vFanins );
302 Vec_PtrFillTwo( vFanins, 2, pAnd0, pAnd1 );
303 pMux = Abc_NtkCreateNodeOr( pNtk, vFanins );
304 Vec_PtrFillTwo( vFanins, 2, pResetN, pMux );
305 pObj->pCopy = Abc_NtkCreateNodeAnd( pNtk, vFanins );
306 }
307 // duplicate internal nodes
308 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
309 Abc_NtkDupObj( pNtk, pObj, 0 );
310 // connect objects
311 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
312 Abc_ObjForEachFanin( pObj, pFanin, k )
313 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
314 // create new POs and reconnect flop inputs
315 Abc_NtkForEachPo( pNtk, pObj, i )
316 {
317 if ( i == nPosOld )
318 break;
319 if ( i < nPosOld - 4 * pNtk->nConstrs )
320 {
321 Abc_NtkDupObj( pNtk, pObj, 0 );
322 Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), "_frame1" );
323 Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
324 continue;
325 }
326 Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), Abc_ObjFanin0(pObj)->pCopy );
327 }
328 Vec_PtrFree( vFanins );
329 Vec_PtrFree( vNodes );
330}
331
348{
349 Vec_Int_t * vArray, * vSet;
350 Abc_Obj_t * pNext; int i;
351 // get the CO set for this object
352 int Entry = Vec_IntEntry(vMap, Abc_ObjId(pObj));
353 if ( Entry != -1 ) // the set is already computed
354 return Entry;
355 // compute a new CO set
356 assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
357 // if there is no fanouts, the set of COs is empty
358 if ( Abc_ObjFanoutNum(pObj) == 0 )
359 {
360 Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), 0 );
361 return 0;
362 }
363 // compute the set for the first fanout
364 Entry = Abc_NtkDetectObjClasses_rec( Abc_ObjFanout0(pObj), vMap, pHash, vTemp );
365 if ( Abc_ObjFanoutNum(pObj) == 1 )
366 {
367 Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), Entry );
368 return Entry;
369 }
370 vSet = Vec_IntAlloc( 16 );
371 // initialize the set with that of first fanout
372 vArray = Hsh_VecReadEntry( pHash, Entry );
373 Vec_IntClear( vSet );
374 Vec_IntAppend( vSet, vArray );
375 // iteratively add sets of other fanouts
376 Abc_ObjForEachFanout( pObj, pNext, i )
377 {
378 if ( i == 0 )
379 continue;
380 Entry = Abc_NtkDetectObjClasses_rec( pNext, vMap, pHash, vTemp );
381 vArray = Hsh_VecReadEntry( pHash, Entry );
382 Vec_IntTwoMerge2( vSet, vArray, vTemp );
383 ABC_SWAP( Vec_Int_t, *vSet, *vTemp );
384 }
385 // create or find new set and map the object into it
386 Entry = Hsh_VecManAdd( pHash, vSet );
387 Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), Entry );
388 Vec_IntFree( vSet );
389 return Entry;
390}
392{
393 Vec_Wec_t * vClasses; // classes of equivalence objects from vObjs
394 Vec_Int_t * vClassMap; // mapping of each CO set into its class in vClasses
395 Vec_Int_t * vClass; // one equivalence class
396 Abc_Obj_t * pObj;
397 int i, iObj, SetId, ClassId;
398 // create hash table to hash sets of CO indexes
399 Hsh_VecMan_t * pHash = Hsh_VecManStart( 1000 );
400 // create elementary sets (each composed of one CO) and map COs into them
401 Vec_Int_t * vMap = Vec_IntStartFull( Abc_NtkObjNumMax(pNtk) );
402 Vec_Int_t * vSet = Vec_IntAlloc( 16 );
403 assert( Abc_NtkIsLogic(pNtk) );
404 // compute empty set
405 SetId = Hsh_VecManAdd( pHash, vSet );
406 assert( SetId == 0 );
407 Abc_NtkForEachCo( pNtk, pObj, i )
408 {
409 Vec_IntFill( vSet, 1, Abc_ObjId(pObj) );
410 SetId = Hsh_VecManAdd( pHash, vSet );
411 Vec_IntWriteEntry( vMap, Abc_ObjId(pObj), SetId );
412 }
413 // make sure the array of objects is sorted
414 Vec_IntSort( vObjs, 0 );
415 // begin from the objects and map their IDs into sets of COs
416 Abc_NtkForEachObjVec( vObjs, pNtk, pObj, i )
417 Abc_NtkDetectObjClasses_rec( pObj, vMap, pHash, vSet );
418 Vec_IntFree( vSet );
419 // create map for mapping CO set its their classes
420 vClassMap = Vec_IntStartFull( Hsh_VecSize(pHash) + 1 );
421 // collect classes of objects
422 vClasses = Vec_WecAlloc( 1000 );
423 Vec_IntForEachEntry( vObjs, iObj, i )
424 {
425 //char * pName = Abc_ObjName( Abc_NtkObj(pNtk, iObj) );
426 // for a given object (iObj), find the ID of its COs set
427 SetId = Vec_IntEntry( vMap, iObj );
428 assert( SetId >= 0 );
429 // for the given CO set, finds its equivalence class
430 ClassId = Vec_IntEntry( vClassMap, SetId );
431 if ( ClassId == -1 ) // there is no equivalence class
432 {
433 // map this CO set into a new equivalence class
434 Vec_IntWriteEntry( vClassMap, SetId, Vec_WecSize(vClasses) );
435 vClass = Vec_WecPushLevel( vClasses );
436 }
437 else // get hold of the equivalence class
438 vClass = Vec_WecEntry( vClasses, ClassId );
439 // add objects to the class
440 Vec_IntPush( vClass, iObj );
441 // print the set for this object
442 //printf( "Object %5d : ", iObj );
443 //Vec_IntPrint( Hsh_VecReadEntry(pHash, SetId) );
444 }
445 // collect arrays of COs for each class
446 *pvCos = Vec_WecStart( Vec_WecSize(vClasses) );
447 Vec_WecForEachLevel( vClasses, vClass, i )
448 {
449 iObj = Vec_IntEntry( vClass, 0 );
450 // for a given object (iObj), find the ID of its COs set
451 SetId = Vec_IntEntry( vMap, iObj );
452 assert( SetId >= 0 );
453 // for the given CO set ID, find the set
454 vSet = Hsh_VecReadEntry( pHash, SetId );
455 Vec_IntAppend( Vec_WecEntry(*pvCos, i), vSet );
456 }
457 Hsh_VecManStop( pHash );
458 Vec_IntFree( vClassMap );
459 Vec_IntFree( vMap );
460 return vClasses;
461}
462void Abc_NtkDetectClassesTest2( Abc_Ntk_t * pNtk, int fVerbose, int fVeryVerbose )
463{
464 Vec_Int_t * vObjs;
465 Vec_Wec_t * vRes, * vCos;
466 // for testing, create the set of object IDs for all combinational inputs (CIs)
467 Abc_Obj_t * pObj; int i;
468 vObjs = Vec_IntAlloc( Abc_NtkCiNum(pNtk) );
469 Abc_NtkForEachCi( pNtk, pObj, i )
470 Vec_IntPush( vObjs, Abc_ObjId(pObj) );
471 // compute equivalence classes of CIs and print them
472 vRes = Abc_NtkDetectObjClasses( pNtk, vObjs, &vCos );
473 Vec_WecPrint( vRes, 0 );
474 Vec_WecPrint( vCos, 0 );
475 // clean up
476 Vec_IntFree( vObjs );
477 Vec_WecFree( vRes );
478 Vec_WecFree( vCos );
479}
480
494{
495 if ( Abc_NodeIsTravIdCurrent(pObj) )
496 return;
497 Abc_NodeSetTravIdCurrent(pObj);
498 if ( Abc_ObjIsCi(pObj) )
499 Vec_IntPush( vCis, Abc_ObjId(pObj) );
500 else
501 {
502 Abc_Obj_t * pFanin; int i;
503 assert( Abc_ObjIsNode( pObj ) );
504 Abc_ObjForEachFanin( pObj, pFanin, i )
505 Abc_NtkFinMiterCollect_rec( pFanin, vCis, vNodes );
506 Vec_IntPush( vNodes, Abc_ObjId(pObj) );
507 }
508}
509void Abc_NtkFinMiterCollect( Abc_Ntk_t * pNtk, Vec_Int_t * vCos, Vec_Int_t * vCis, Vec_Int_t * vNodes )
510{
511 Abc_Obj_t * pObj; int i;
512 Vec_IntClear( vCis );
513 Vec_IntClear( vNodes );
514 Abc_NtkIncrementTravId( pNtk );
515 Abc_NtkForEachObjVec( vCos, pNtk, pObj, i )
516 Abc_NtkFinMiterCollect_rec( Abc_ObjFanin0(pObj), vCis, vNodes );
517}
518
530void Mio_LibGateSimulate( Mio_Gate_t * pGate, word * ppFaninSims[6], int nWords, word * pObjSim )
531{
532 int i, w, nVars = Mio_GateReadPinNum(pGate);
533 Vec_Int_t * vExpr = Mio_GateReadExpr( pGate );
534 assert( nVars <= 6 );
535 for ( w = 0; w < nWords; w++ )
536 {
537 word uFanins[6];
538 for ( i = 0; i < nVars; i++ )
539 uFanins[i] = ppFaninSims[i][w];
540 pObjSim[w] = Exp_Truth6( nVars, vExpr, uFanins );
541 }
542}
543
555int Mio_LibGateSimulateOne( Mio_Gate_t * pGate, int iBits[6] )
556{
557 int nVars = Mio_GateReadPinNum(pGate);
558 int i, iMint = 0;
559 for ( i = 0; i < nVars; i++ )
560 if ( iBits[i] )
561 iMint |= (1 << i);
562 return Abc_InfoHasBit( (unsigned *)Mio_GateReadTruthP(pGate), iMint );
563}
564
576int Mio_LibGateSimulateGia( Gia_Man_t * pGia, Mio_Gate_t * pGate, int iLits[6], Vec_Int_t * vLits )
577{
578 int i, nVars = Mio_GateReadPinNum(pGate);
579 Vec_Int_t * vExpr = Mio_GateReadExpr( pGate );
580 if ( Exp_IsConst0(vExpr) )
581 return 0;
582 if ( Exp_IsConst1(vExpr) )
583 return 1;
584 if ( Exp_IsLit(vExpr) )
585 {
586 int Index0 = Vec_IntEntry(vExpr,0) >> 1;
587 int fCompl0 = Vec_IntEntry(vExpr,0) & 1;
588 assert( Index0 < nVars );
589 return Abc_LitNotCond( iLits[Index0], fCompl0 );
590 }
591 Vec_IntClear( vLits );
592 for ( i = 0; i < nVars; i++ )
593 Vec_IntPush( vLits, iLits[i] );
594 for ( i = 0; i < Exp_NodeNum(vExpr); i++ )
595 {
596 int Index0 = Vec_IntEntry( vExpr, 2*i+0 ) >> 1;
597 int Index1 = Vec_IntEntry( vExpr, 2*i+1 ) >> 1;
598 int fCompl0 = Vec_IntEntry( vExpr, 2*i+0 ) & 1;
599 int fCompl1 = Vec_IntEntry( vExpr, 2*i+1 ) & 1;
600 Vec_IntPush( vLits, Gia_ManHashAnd( pGia, Abc_LitNotCond(Vec_IntEntry(vLits, Index0), fCompl0), Abc_LitNotCond(Vec_IntEntry(vLits, Index1), fCompl1) ) );
601 }
602 return Abc_LitNotCond( Vec_IntEntryLast(vLits), Vec_IntEntryLast(vExpr) & 1 );
603}
604
616static inline int Abc_NtkFinSimOneLit( Gia_Man_t * pNew, Abc_Obj_t * pObj, int Type, Vec_Int_t * vMap, int n, Vec_Int_t * vTemp )
617{
618 if ( Abc_NtkIsMappedLogic(pObj->pNtk) && Type >= 0 )
619 {
620 extern int Mio_LibGateSimulateGia( Gia_Man_t * pGia, Mio_Gate_t * pGate, int iLits[6], Vec_Int_t * vLits );
621 Mio_Library_t * pLib = (Mio_Library_t *)pObj->pNtk->pManFunc;
622 int i, Lits[6];
623 for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
624 Lits[i] = Vec_IntEntry( vMap, Abc_Var2Lit(Abc_ObjFaninId(pObj, i), n) );
625 return Mio_LibGateSimulateGia( pNew, Mio_LibraryReadGateById(pLib, Type), Lits, vTemp );
626 }
627 else
628 {
629 int iLit0 = Abc_ObjFaninNum(pObj) > 0 ? Vec_IntEntry( vMap, Abc_Var2Lit(Abc_ObjFaninId0(pObj), n) ) : -1;
630 int iLit1 = Abc_ObjFaninNum(pObj) > 1 ? Vec_IntEntry( vMap, Abc_Var2Lit(Abc_ObjFaninId1(pObj), n) ) : -1;
631 assert( Type != ABC_FIN_NEG );
632 if ( Type == ABC_FIN_SA0 ) return 0;
633 if ( Type == ABC_FIN_SA1 ) return 1;
634 if ( Type == ABC_FIN_RDOB_BUFF ) return iLit0;
635 if ( Type == ABC_FIN_RDOB_NOT ) return Abc_LitNot( iLit0 );
636 if ( Type == ABC_FIN_RDOB_AND ) return Gia_ManHashAnd( pNew, iLit0, iLit1 );
637 if ( Type == ABC_FIN_RDOB_OR ) return Gia_ManHashOr( pNew, iLit0, iLit1 );
638 if ( Type == ABC_FIN_RDOB_XOR ) return Gia_ManHashXor( pNew, iLit0, iLit1 );
639 if ( Type == ABC_FIN_RDOB_NAND ) return Abc_LitNot(Gia_ManHashAnd( pNew, iLit0, iLit1 ));
640 if ( Type == ABC_FIN_RDOB_NOR ) return Abc_LitNot(Gia_ManHashOr( pNew, iLit0, iLit1 ));
641 if ( Type == ABC_FIN_RDOB_NXOR ) return Abc_LitNot(Gia_ManHashXor( pNew, iLit0, iLit1 ));
642 assert( 0 );
643 return -1;
644 }
645}
646static inline int Abc_NtkFinSimOneBit( Abc_Obj_t * pObj, int Type, Vec_Wrd_t * vSims, int nWords, int iBit )
647{
648 if ( Abc_NtkIsMappedLogic(pObj->pNtk) && Type >= 0 )
649 {
650 extern int Mio_LibGateSimulateOne( Mio_Gate_t * pGate, int iBits[6] );
651 Mio_Library_t * pLib = (Mio_Library_t *)pObj->pNtk->pManFunc;
652 int i, iBits[6];
653 for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
654 {
655 word * pSim0 = Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId(pObj, i) );
656 iBits[i] = Abc_InfoHasBit( (unsigned*)pSim0, iBit );
657 }
658 return Mio_LibGateSimulateOne( Mio_LibraryReadGateById(pLib, Type), iBits );
659 }
660 else
661 {
662 word * pSim0 = Abc_ObjFaninNum(pObj) > 0 ? Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId0(pObj) ) : NULL;
663 word * pSim1 = Abc_ObjFaninNum(pObj) > 1 ? Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId1(pObj) ) : NULL;
664 int iBit0 = Abc_ObjFaninNum(pObj) > 0 ? Abc_InfoHasBit( (unsigned*)pSim0, iBit ) : -1;
665 int iBit1 = Abc_ObjFaninNum(pObj) > 1 ? Abc_InfoHasBit( (unsigned*)pSim1, iBit ) : -1;
666 assert( Type != ABC_FIN_NEG );
667 if ( Type == ABC_FIN_SA0 ) return 0;
668 if ( Type == ABC_FIN_SA1 ) return 1;
669 if ( Type == ABC_FIN_RDOB_BUFF ) return iBit0;
670 if ( Type == ABC_FIN_RDOB_NOT ) return !iBit0;
671 if ( Type == ABC_FIN_RDOB_AND ) return iBit0 & iBit1;
672 if ( Type == ABC_FIN_RDOB_OR ) return iBit0 | iBit1;
673 if ( Type == ABC_FIN_RDOB_XOR ) return iBit0 ^ iBit1;
674 if ( Type == ABC_FIN_RDOB_NAND ) return !(iBit0 & iBit1);
675 if ( Type == ABC_FIN_RDOB_NOR ) return !(iBit0 | iBit1);
676 if ( Type == ABC_FIN_RDOB_NXOR ) return !(iBit0 ^ iBit1);
677 assert( 0 );
678 return -1;
679 }
680}
681static inline void Abc_NtkFinSimOneWord( Abc_Obj_t * pObj, int Type, Vec_Wrd_t * vSims, int nWords )
682{
683 if ( Abc_NtkIsMappedLogic(pObj->pNtk) )
684 {
685 extern void Mio_LibGateSimulate( Mio_Gate_t * pGate, word * ppFaninSims[6], int nWords, word * pObjSim );
686 word * ppSims[6]; int i;
687 word * pSim = Vec_WrdEntryP( vSims, nWords * Abc_ObjId(pObj) );
688 assert( Type == -1 );
689 for ( i = 0; i < Abc_ObjFaninNum(pObj); i++ )
690 ppSims[i] = Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId(pObj, i) );
691 Mio_LibGateSimulate( (Mio_Gate_t *)pObj->pData, ppSims, nWords, pSim );
692 }
693 else
694 {
695 word * pSim = Vec_WrdEntryP( vSims, nWords * Abc_ObjId(pObj) ); int w;
696 word * pSim0 = Abc_ObjFaninNum(pObj) > 0 ? Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId0(pObj) ) : NULL;
697 word * pSim1 = Abc_ObjFaninNum(pObj) > 1 ? Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId1(pObj) ) : NULL;
698 assert( Type != ABC_FIN_NEG );
699 if ( Type == ABC_FIN_SA0 ) for ( w = 0; w < nWords; w++ ) pSim[w] = 0;
700 else if ( Type == ABC_FIN_SA1 ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~((word)0);
701 else if ( Type == ABC_FIN_RDOB_BUFF ) for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w];
702 else if ( Type == ABC_FIN_RDOB_NOT ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~pSim0[w];
703 else if ( Type == ABC_FIN_RDOB_AND ) for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w] & pSim1[w];
704 else if ( Type == ABC_FIN_RDOB_OR ) for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w] | pSim1[w];
705 else if ( Type == ABC_FIN_RDOB_XOR ) for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w] ^ pSim1[w];
706 else if ( Type == ABC_FIN_RDOB_NAND ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~(pSim0[w] & pSim1[w]);
707 else if ( Type == ABC_FIN_RDOB_NOR ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~(pSim0[w] | pSim1[w]);
708 else if ( Type == ABC_FIN_RDOB_NXOR ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~(pSim0[w] ^ pSim1[w]);
709 else assert( 0 );
710 }
711}
712
713
714// returns 1 if the functionality with indexes i1 and i2 is the same
715static inline int Abc_NtkFinCompareSimTwo( Abc_Ntk_t * pNtk, Vec_Int_t * vCos, Vec_Wrd_t * vSims, int nWords, int i1, int i2 )
716{
717 Abc_Obj_t * pObj; int i;
718 assert( i1 != i2 );
719 Abc_NtkForEachObjVec( vCos, pNtk, pObj, i )
720 {
721 word * pSim0 = Vec_WrdEntryP( vSims, nWords * Abc_ObjFaninId0(pObj) );
722 if ( Abc_InfoHasBit((unsigned*)pSim0, i1) != Abc_InfoHasBit((unsigned*)pSim0, i2) )
723 return 0;
724 }
725 return 1;
726}
727
728Gia_Man_t * Abc_NtkFinMiterToGia( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t * vCos, Vec_Int_t * vCis, Vec_Int_t * vNodes,
729 int iObjs[2], int Types[2], Vec_Int_t * vLits )
730{
731 Gia_Man_t * pNew = NULL, * pTemp;
732 Abc_Obj_t * pObj;
733 Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
734 int n, i, Type, iMiter, iLit, * pLits;
735 // create AIG manager
736 pNew = Gia_ManStart( 1000 );
737 pNew->pName = Abc_UtilStrsav( pNtk->pName );
738 pNew->pSpec = Abc_UtilStrsav( pNtk->pSpec );
739 Gia_ManHashStart( pNew );
740 // create inputs
741 Abc_NtkForEachObjVec( vCis, pNtk, pObj, i )
742 {
743 iLit = Gia_ManAppendCi(pNew);
744 for ( n = 0; n < 2; n++ )
745 {
746 if ( iObjs[n] != (int)Abc_ObjId(pObj) )
747 Vec_IntWriteEntry( vLits, Abc_Var2Lit(Abc_ObjId(pObj), n), iLit );
748 else if ( Types[n] != ABC_FIN_NEG )
749 Vec_IntWriteEntry( vLits, Abc_Var2Lit(Abc_ObjId(pObj), n), Abc_NtkFinSimOneLit(pNew, pObj, Types[n], vLits, n, vTemp) );
750 else // if ( iObjs[n] == (int)Abc_ObjId(pObj) && Types[n] == ABC_FIN_NEG )
751 Vec_IntWriteEntry( vLits, Abc_Var2Lit(Abc_ObjId(pObj), n), Abc_LitNot(iLit) );
752 }
753 }
754 // create internal nodes
755 Abc_NtkForEachObjVec( vNodes, pNtk, pObj, i )
756 {
757 Type = Abc_NtkIsMappedLogic(pNtk) ? Mio_GateReadCell((Mio_Gate_t *)pObj->pData) : Vec_IntEntry(vTypes, Abc_ObjId(pObj));
758 for ( n = 0; n < 2; n++ )
759 {
760 if ( iObjs[n] != (int)Abc_ObjId(pObj) )
761 Vec_IntWriteEntry( vLits, Abc_Var2Lit(Abc_ObjId(pObj), n), Abc_NtkFinSimOneLit(pNew, pObj, Type, vLits, n, vTemp) );
762 else if ( Types[n] != ABC_FIN_NEG )
763 Vec_IntWriteEntry( vLits, Abc_Var2Lit(Abc_ObjId(pObj), n), Abc_NtkFinSimOneLit(pNew, pObj, Types[n], vLits, n, vTemp) );
764 else // if ( iObjs[n] == (int)Abc_ObjId(pObj) && Types[n] == ABC_FIN_NEG )
765 Vec_IntWriteEntry( vLits, Abc_Var2Lit(Abc_ObjId(pObj), n), Abc_LitNot(Abc_NtkFinSimOneLit(pNew, pObj, Type, vLits, n, vTemp)) );
766 }
767 }
768 // create comparator
769 iMiter = 0;
770 Abc_NtkForEachObjVec( vCos, pNtk, pObj, i )
771 {
772 pLits = Vec_IntEntryP( vLits, Abc_Var2Lit(Abc_ObjFaninId0(pObj), 0) );
773 iLit = Gia_ManHashXor( pNew, pLits[0], pLits[1] );
774 iMiter = Gia_ManHashOr( pNew, iMiter, iLit );
775 }
776 Gia_ManAppendCo( pNew, iMiter );
777 // perform cleanup
778 pNew = Gia_ManCleanup( pTemp = pNew );
779 Gia_ManStop( pTemp );
780 Vec_IntFree( vTemp );
781 return pNew;
782}
783void Abc_NtkFinSimulateOne( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t * vCos, Vec_Int_t * vCis, Vec_Int_t * vNodes,
784 Vec_Wec_t * vMap2, Vec_Int_t * vPat, Vec_Wrd_t * vSims, int nWords, Vec_Int_t * vPairs, Vec_Wec_t * vRes, int iLevel, int iItem )
785{
786 Abc_Obj_t * pObj;
787 Vec_Int_t * vClass, * vArray;
788 int i, Counter = 0;
789 int nItems = Vec_WecSizeSize(vRes);
790 assert( nItems == Vec_WecSizeSize(vMap2) );
791 assert( nItems <= 128 * nWords );
792 // assign inputs
793 assert( Vec_IntSize(vPat) == Vec_IntSize(vCis) );
794 Abc_NtkForEachObjVec( vCis, pNtk, pObj, i )
795 {
796 int w, iObj = Abc_ObjId( pObj );
797 word Init = Vec_IntEntry(vPat, i) ? ~((word)0) : 0;
798 word * pSim = Vec_WrdEntryP( vSims, nWords * Abc_ObjId(pObj) );
799 for ( w = 0; w < nWords; w++ )
800 pSim[w] = Init;
801 vArray = Vec_WecEntry(vMap2, iObj);
802 if ( Vec_IntSize(vArray) > 0 )
803 {
804 int k, iFin, Index, iObj, Type;
805 Vec_IntForEachEntryDouble( vArray, iFin, Index, k )
806 {
807 assert( Index < 64 );
808 iObj = Vec_IntEntry( vPairs, 2*iFin );
809 assert( iObj == (int)Abc_ObjId(pObj) );
810 Type = Vec_IntEntry( vPairs, 2*iFin+1 );
811 assert( Type == ABC_FIN_NEG || Type == ABC_FIN_SA0 || Type == ABC_FIN_SA1 );
812 if ( Type == ABC_FIN_NEG || Abc_InfoHasBit((unsigned *)pSim, Index) != Abc_NtkFinSimOneBit(pObj, Type, vSims, nWords, Index) )
813 Abc_InfoXorBit( (unsigned *)pSim, Index );
814 Counter++;
815 }
816 }
817 }
818 // simulate internal nodes
819 Abc_NtkForEachObjVec( vNodes, pNtk, pObj, i )
820 {
821 int iObj = Abc_ObjId( pObj );
822 int Type = Abc_NtkIsMappedLogic(pNtk) ? -1 : Vec_IntEntry( vTypes, iObj );
823 word * pSim = Vec_WrdEntryP( vSims, nWords * Abc_ObjId(pObj) );
824 Abc_NtkFinSimOneWord( pObj, Type, vSims, nWords );
825 vArray = Vec_WecEntry(vMap2, iObj);
826 if ( Vec_IntSize(vArray) > 0 )
827 {
828 int k, iFin, Index, iObj, Type;
829 Vec_IntForEachEntryDouble( vArray, iFin, Index, k )
830 {
831 assert( Index < 64 * nWords );
832 iObj = Vec_IntEntry( vPairs, 2*iFin );
833 assert( iObj == (int)Abc_ObjId(pObj) );
834 Type = Vec_IntEntry( vPairs, 2*iFin+1 );
835 if ( Type == ABC_FIN_NEG || Abc_InfoHasBit((unsigned *)pSim, Index) != Abc_NtkFinSimOneBit(pObj, Type, vSims, nWords, Index) )
836 Abc_InfoXorBit( (unsigned *)pSim, Index );
837 Counter++;
838 }
839 }
840 }
841 assert( nItems == 2*Counter );
842
843 // confirm no refinement
844 Vec_WecForEachLevelStop( vRes, vClass, i, iLevel+1 )
845 {
846 int k, iFin, Index, Value;
847 int Index0 = Vec_IntEntry( vClass, 1 );
848 Vec_IntForEachEntryDoubleStart( vClass, iFin, Index, k, 2 )
849 {
850 if ( i == iLevel && k/2 >= iItem )
851 break;
852 //printf( "Double-checking pair %d and %d\n", iFin0, iFin );
853 Value = Abc_NtkFinCompareSimTwo( pNtk, vCos, vSims, nWords, Index0, Index );
854 assert( Value ); // the same value
855 }
856 }
857
858 // check refinement
859 Vec_WecForEachLevelStart( vRes, vClass, i, iLevel )
860 {
861 int k, iFin, Index, Value, Index0 = Vec_IntEntry(vClass, 1);
862 int j = (i == iLevel) ? 2*iItem : 2;
863 Vec_Int_t * vNewClass = NULL;
864 Vec_IntForEachEntryDoubleStart( vClass, iFin, Index, k, j )
865 {
866 Value = Abc_NtkFinCompareSimTwo( pNtk, vCos, vSims, nWords, Index0, Index );
867 if ( Value ) // the same value
868 {
869 Vec_IntWriteEntry( vClass, j++, iFin );
870 Vec_IntWriteEntry( vClass, j++, Index );
871 continue;
872 }
873 // create new class
874 vNewClass = vNewClass ? vNewClass : Vec_WecPushLevel( vRes );
875 Vec_IntPushTwo( vNewClass, iFin, Index ); // index and first entry
876 vClass = Vec_WecEntry( vRes, i );
877 }
878 Vec_IntShrink( vClass, j );
879 }
880}
881
893Vec_Int_t * Abc_NtkFinCheckPair( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t * vCos, Vec_Int_t * vCis, Vec_Int_t * vNodes, int iObjs[2], int Types[2], Vec_Int_t * vLits )
894{
895 Gia_Man_t * pGia = Abc_NtkFinMiterToGia( pNtk, vTypes, vCos, vCis, vNodes, iObjs, Types, vLits );
896 if ( Gia_ManAndNum(pGia) == 0 && Gia_ObjIsConst0(Gia_ObjFanin0(Gia_ManCo(pGia, 0))) )
897 {
898 Vec_Int_t * vPat = Gia_ObjFaninC0(Gia_ManCo(pGia, 0)) ? Vec_IntStart(Vec_IntSize(vCis)) : NULL;
899 Gia_ManStop( pGia );
900 return vPat;
901 }
902 else
903 {
904 Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGia, 8, 0, 1, 0, 0 );
905 sat_solver * pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
906 if ( pSat == NULL )
907 {
908 Gia_ManStop( pGia );
909 Cnf_DataFree( pCnf );
910 return NULL;
911 }
912 else
913 {
914 int i, nConfLimit = 10000;
915 Vec_Int_t * vPat = NULL;
916 int status, iVarBeg = pCnf->nVars - Gia_ManPiNum(pGia);// - 1;
917 //Gia_AigerWrite( pGia, "temp_detect.aig", 0, 0, 0 );
918 Gia_ManStop( pGia );
919 Cnf_DataFree( pCnf );
920 status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
921 if ( status == l_Undef )
922 vPat = Vec_IntAlloc(0);
923 else if ( status == l_True )
924 {
925 vPat = Vec_IntAlloc( Vec_IntSize(vCis) );
926 for ( i = 0; i < Vec_IntSize(vCis); i++ )
927 Vec_IntPush( vPat, sat_solver_var_value(pSat, iVarBeg+i) );
928 }
929 //printf( "%d ", sat_solver_nconflicts(pSat) );
930 sat_solver_delete( pSat );
931 return vPat;
932 }
933 }
934}
935
936
948void Abc_NtkFinLocalSetup( Vec_Int_t * vPairs, Vec_Int_t * vList, Vec_Wec_t * vMap2, Vec_Int_t * vResArray )
949{
950 int i, iFin;
951 Vec_IntClear( vResArray );
952 Vec_IntForEachEntry( vList, iFin, i )
953 {
954 int iObj = Vec_IntEntry( vPairs, 2*iFin );
955 Vec_Int_t * vArray = Vec_WecEntry( vMap2, iObj );
956 Vec_IntPushTwo( vArray, iFin, i );
957 Vec_IntPushTwo( vResArray, iFin, i );
958 }
959}
960void Abc_NtkFinLocalSetdown( Vec_Int_t * vPairs, Vec_Int_t * vList, Vec_Wec_t * vMap2 )
961{
962 int i, iFin;
963 Vec_IntForEachEntry( vList, iFin, i )
964 {
965 int iObj = Vec_IntEntry( vPairs, 2*iFin );
966 Vec_Int_t * vArray = Vec_WecEntry( vMap2, iObj );
967 Vec_IntClear( vArray );
968 }
969}
970int Abc_NtkFinRefinement( Abc_Ntk_t * pNtk, Vec_Int_t * vTypes, Vec_Int_t * vCos, Vec_Int_t * vCis, Vec_Int_t * vNodes,
971 Vec_Int_t * vPairs, Vec_Int_t * vList, Vec_Wec_t * vMap2, Vec_Wec_t * vResult )
972{
973 Vec_Wec_t * vRes = Vec_WecAlloc( 100 );
974 int nWords = Abc_Bit6WordNum( Vec_IntSize(vList) );
975 Vec_Wrd_t * vSims = Vec_WrdStart( nWords * Abc_NtkObjNumMax(pNtk) ); // simulation info for each object
976 Vec_Int_t * vLits = Vec_IntStart( 2*Abc_NtkObjNumMax(pNtk) ); // two literals for each object
977 Vec_Int_t * vPat, * vClass, * vArray;
978 int i, k, iFin, Index, nCalls = 0;
979 // prepare
980 vArray = Vec_WecPushLevel( vRes );
981 Abc_NtkFinLocalSetup( vPairs, vList, vMap2, vArray );
982 // try all-0/all-1 pattern
983 for ( i = 0; i < 2; i++ )
984 {
985 vPat = Vec_IntAlloc( Vec_IntSize(vCis) );
986 Vec_IntFill( vPat, Vec_IntSize(vCis), i );
987 Abc_NtkFinSimulateOne( pNtk, vTypes, vCos, vCis, vNodes, vMap2, vPat, vSims, nWords, vPairs, vRes, 0, 1 );
988 Vec_IntFree( vPat );
989 }
990 // explore the classes
991 //Vec_WecPrint( vRes, 0 );
992 Vec_WecForEachLevel( vRes, vClass, i )
993 {
994 int iFin0 = Vec_IntEntry( vClass, 0 );
995 Vec_IntForEachEntryDoubleStart( vClass, iFin, Index, k, 2 )
996 {
997 int Objs[2] = { Vec_IntEntry(vPairs, 2*iFin0), Vec_IntEntry(vPairs, 2*iFin) };
998 int Types[2] = { Vec_IntEntry(vPairs, 2*iFin0+1), Vec_IntEntry(vPairs, 2*iFin+1) };
999 nCalls++;
1000 //printf( "Checking pair %d and %d.\n", iFin0, iFin );
1001 vPat = Abc_NtkFinCheckPair( pNtk, vTypes, vCos, vCis, vNodes, Objs, Types, vLits );
1002 if ( vPat == NULL ) // proved
1003 continue;
1004 assert( Vec_IntEntry(vClass, k) == iFin );
1005 if ( Vec_IntSize(vPat) == 0 )
1006 {
1007 Vec_Int_t * vNewClass = Vec_WecPushLevel( vRes );
1008 Vec_IntPushTwo( vNewClass, iFin, Index ); // index and first entry
1009 vClass = Vec_WecEntry( vRes, i );
1010 Vec_IntDrop( vClass, k+1 );
1011 Vec_IntDrop( vClass, k );
1012 }
1013 else // resimulate and refine
1014 Abc_NtkFinSimulateOne( pNtk, vTypes, vCos, vCis, vNodes, vMap2, vPat, vSims, nWords, vPairs, vRes, i, k/2 );
1015 Vec_IntFree( vPat );
1016 // make sure refinement happened (k'th entry is now absent or different)
1017 vClass = Vec_WecEntry( vRes, i );
1018 assert( Vec_IntSize(vClass) <= k || Vec_IntEntry(vClass, k) != iFin );
1019 k -= 2;
1020 //Vec_WecPrint( vRes, 0 );
1021 }
1022 }
1023 // unprepare
1024 Abc_NtkFinLocalSetdown( vPairs, vList, vMap2 );
1025 // reload proved equivs into the final array
1026 Vec_WecForEachLevel( vRes, vArray, i )
1027 {
1028 assert( Vec_IntSize(vArray) % 2 == 0 );
1029 if ( Vec_IntSize(vArray) <= 2 )
1030 continue;
1031 vClass = Vec_WecPushLevel( vResult );
1032 Vec_IntForEachEntryDouble( vArray, iFin, Index, k )
1033 Vec_IntPush( vClass, iFin );
1034 }
1035 Vec_WecFree( vRes );
1036 Vec_WrdFree( vSims );
1037 Vec_IntFree( vLits );
1038 return nCalls;
1039}
1040
1052static inline int Abc_ObjFinGateType( Abc_Obj_t * pNode )
1053{
1054 char * pSop = (char *)pNode->pData;
1055 if ( !strcmp(pSop, "1 1\n") ) return ABC_FIN_RDOB_BUFF;
1056 if ( !strcmp(pSop, "0 1\n") ) return ABC_FIN_RDOB_NOT;
1057 if ( !strcmp(pSop, "11 1\n") ) return ABC_FIN_RDOB_AND;
1058 if ( !strcmp(pSop, "11 0\n") ) return ABC_FIN_RDOB_NAND;
1059 if ( !strcmp(pSop, "00 0\n") ) return ABC_FIN_RDOB_OR;
1060 if ( !strcmp(pSop, "00 1\n") ) return ABC_FIN_RDOB_NOR;
1061 if ( !strcmp(pSop, "01 1\n10 1\n") ) return ABC_FIN_RDOB_XOR;
1062 if ( !strcmp(pSop, "11 1\n00 1\n") ) return ABC_FIN_RDOB_NXOR;
1063 return ABC_FIN_NONE;
1064}
1066{
1067 Abc_Obj_t * pObj; int i;
1068 Abc_NtkForEachNode( pNtk, pObj, i )
1069 if ( Abc_ObjFinGateType(pObj) == ABC_FIN_NONE )
1070 return i;
1071 return 0;
1072}
1074{
1075 Mio_Library_t * pLib = (Mio_Library_t *)pNtk->pManFunc;
1076 int i, iObj, Type;
1077 Vec_IntForEachEntryDoubleStart( pNtk->vFins, iObj, Type, i, 2 )
1078 {
1079 Abc_Obj_t * pObj = Abc_NtkObj( pNtk, iObj );
1080 Mio_Gate_t * pGateFlt, * pGateObj = (Mio_Gate_t *)pObj->pData;
1081 if ( Type < 0 ) // SA0, SA1, NEG
1082 continue;
1083 pGateFlt = Mio_LibraryReadGateById( pLib, Type );
1084 if ( Mio_GateReadPinNum(pGateFlt) < 1 )
1085 continue;
1086 if ( Mio_GateReadPinNum(pGateObj) != Mio_GateReadPinNum(pGateFlt) )
1087 return iObj;
1088 }
1089 return 0;
1090}
1092{
1093 Abc_Obj_t * pObj; int i;
1094 Vec_Int_t * vObjs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1095 Abc_NtkForEachNode( pNtk, pObj, i )
1096 Vec_IntWriteEntry( vObjs, Abc_ObjId(pObj), Abc_ObjFinGateType(pObj) );
1097 return vObjs;
1098}
1099Vec_Int_t * Abc_NtkFinComputeObjects( Vec_Int_t * vPairs, Vec_Wec_t ** pvMap, int nObjs )
1100{
1101 int i, iObj, Type;
1102 Vec_Int_t * vObjs = Vec_IntAlloc( 100 );
1103 *pvMap = Vec_WecStart( nObjs );
1104 Vec_IntForEachEntryDoubleStart( vPairs, iObj, Type, i, 2 )
1105 {
1106 Vec_IntPush( vObjs, iObj );
1107 Vec_WecPush( *pvMap, iObj, i/2 );
1108 }
1109 Vec_IntUniqify( vObjs );
1110 return vObjs;
1111}
1113{
1114 int i, iObj;
1115 Vec_Int_t * vList = Vec_IntAlloc( 100 );
1116 Vec_IntForEachEntry( vClass, iObj, i )
1117 Vec_IntAppend( vList, Vec_WecEntry(vMap, iObj) );
1118 return vList;
1119}
1121{
1122 int i, Counter = 0;
1123 Vec_Int_t * vLevel;
1124 Vec_WecForEachLevel( vClasses, vLevel, i )
1125 Counter += Vec_IntSize(vLevel) - 1;
1126 return Counter;
1127}
1129{
1130 Vec_Int_t * vTypes = NULL; // gate types
1131 Vec_Int_t * vPairs; // original info as a set of pairs (ObjId, TypeId)
1132 Vec_Int_t * vObjs; // all those objects that have some fin
1133 Vec_Wec_t * vMap; // for each object, the set of fins
1134 Vec_Wec_t * vMap2; // for each local object, the set of pairs (Info, Index)
1135 Vec_Wec_t * vClasses; // classes of objects
1136 Vec_Wec_t * vCoSets; // corresponding CO sets
1137 Vec_Int_t * vClass; // one class
1138 Vec_Int_t * vCoSet; // one set of COs
1139 Vec_Int_t * vCiSet; // one set of CIs
1140 Vec_Int_t * vNodeSet; // one set of nodes
1141 Vec_Int_t * vList; // one info list
1142 Vec_Wec_t * vResult; // resulting equivalences
1143 int i, iObj, nCalls;
1144 if ( pNtk->vFins == NULL )
1145 {
1146 printf( "Current network does not have the required info.\n" );
1147 return NULL;
1148 }
1149 assert( Abc_NtkIsSopLogic(pNtk) || Abc_NtkIsMappedLogic(pNtk) );
1150 if ( Abc_NtkIsSopLogic(pNtk) )
1151 {
1152 iObj = Abc_NtkFinCheckTypesOk(pNtk);
1153 if ( iObj )
1154 {
1155 printf( "Current network contains unsupported gate types (for example, see node \"%s\").\n", Abc_ObjName(Abc_NtkObj(pNtk, iObj)) );
1156 return NULL;
1157 }
1158 vTypes = Abc_NtkFinComputeTypes( pNtk );
1159 }
1160 else if ( Abc_NtkIsMappedLogic(pNtk) )
1161 {
1162 iObj = Abc_NtkFinCheckTypesOk2(pNtk);
1163 if ( iObj )
1164 {
1165 printf( "Current network has mismatch between mapped gate size and fault gate size (for example, see node \"%s\").\n", Abc_ObjName(Abc_NtkObj(pNtk, iObj)) );
1166 return NULL;
1167 }
1168 }
1169 else assert( 0 );
1170 //Abc_NtkFrameExtend( pNtk );
1171 // collect data
1172 vPairs = pNtk->vFins;
1173 vObjs = Abc_NtkFinComputeObjects( vPairs, &vMap, Abc_NtkObjNumMax(pNtk) );
1174 vClasses = Abc_NtkDetectObjClasses( pNtk, vObjs, &vCoSets );
1175 // refine classes
1176 vCiSet = Vec_IntAlloc( 1000 );
1177 vNodeSet = Vec_IntAlloc( 1000 );
1178 vMap2 = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
1179 vResult = Vec_WecAlloc( 1000 );
1180 Vec_WecForEachLevel( vClasses, vClass, i )
1181 {
1182 // extract one window
1183 vCoSet = Vec_WecEntry( vCoSets, i );
1184 Abc_NtkFinMiterCollect( pNtk, vCoSet, vCiSet, vNodeSet );
1185 // refine one class
1186 vList = Abc_NtkFinCreateList( vMap, vClass );
1187 nCalls = Abc_NtkFinRefinement( pNtk, vTypes, vCoSet, vCiSet, vNodeSet, vPairs, vList, vMap2, vResult );
1188 if ( fVerbose )
1189 printf( "Group %4d : Obj =%4d. Fins =%4d. CI =%5d. CO =%5d. Node =%6d. SAT calls =%5d.\n",
1190 i, Vec_IntSize(vClass), Vec_IntSize(vList), Vec_IntSize(vCiSet), Vec_IntSize(vCoSet), Vec_IntSize(vNodeSet), nCalls );
1191 Vec_IntFree( vList );
1192 }
1193 // sort entries in each array
1194 Vec_WecForEachLevel( vResult, vClass, i )
1195 Vec_IntSort( vClass, 0 );
1196 // sort by the index of the first entry
1197 Vec_WecSortByFirstInt( vResult, 0 );
1198 // cleanup
1199 Vec_IntFreeP( & vTypes );
1200 Vec_IntFree( vObjs );
1201 Vec_WecFree( vClasses );
1202 Vec_WecFree( vMap );
1203 Vec_WecFree( vMap2 );
1204 Vec_WecFree( vCoSets );
1205 Vec_IntFree( vCiSet );
1206 Vec_IntFree( vNodeSet );
1207 return vResult;
1208}
1209
1222{
1223 Vec_Int_t * vClass;
1224 int i, k, Entry;
1225 Vec_WecForEachLevel( vClasses, vClass, i )
1226 Vec_IntForEachEntryStart( vClass, Entry, k, 1 )
1227 printf( "%d %d\n", Vec_IntEntry(vClass, 0), Entry );
1228}
1229
1241void Abc_NtkDetectClassesTest( Abc_Ntk_t * pNtk, int fSeq, int fVerbose, int fVeryVerbose )
1242{
1243 Vec_Wec_t * vResult;
1244 abctime clk = Abc_Clock();
1245 if ( fSeq )
1246 Abc_NtkFrameExtend( pNtk );
1247 vResult = Abc_NtkDetectFinClasses( pNtk, fVerbose );
1248 printf( "Computed %d equivalence classes with %d item pairs. ", Vec_WecSize(vResult), Abc_NtkFinCountPairs(vResult) );
1249 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1250 if ( fVeryVerbose )
1251 Vec_WecPrint( vResult, 1 );
1252// if ( fVerbose )
1253// Abc_NtkPrintFinResults( vResult );
1254 Vec_WecFree( vResult );
1255}
1256
1257
1261
1262
1264
char * Io_WriteFinType(int Type)
Definition abcDetect.c:136
void Abc_NtkFinMiterCollect_rec(Abc_Obj_t *pObj, Vec_Int_t *vCis, Vec_Int_t *vNodes)
Definition abcDetect.c:493
Vec_Int_t * Abc_NtkFinCreateList(Vec_Wec_t *vMap, Vec_Int_t *vClass)
Definition abcDetect.c:1112
void Abc_NtkDetectClassesTest2(Abc_Ntk_t *pNtk, int fVerbose, int fVeryVerbose)
Definition abcDetect.c:462
void Abc_NtkDetectClassesTest(Abc_Ntk_t *pNtk, int fSeq, int fVerbose, int fVeryVerbose)
Definition abcDetect.c:1241
Abc_FinType_t
DECLARATIONS ///.
Definition abcDetect.c:35
@ ABC_FIN_SA1
Definition abcDetect.c:38
@ ABC_FIN_RDOB_NAND
Definition abcDetect.c:41
@ ABC_FIN_RDOB_OR
Definition abcDetect.c:42
@ ABC_FIN_NONE
Definition abcDetect.c:36
@ ABC_FIN_SA0
Definition abcDetect.c:37
@ ABC_FIN_RDOB_XOR
Definition abcDetect.c:44
@ ABC_FIN_RDOB_LAST
Definition abcDetect.c:48
@ ABC_FIN_RDOB_NOT
Definition abcDetect.c:46
@ ABC_FIN_RDOB_NOR
Definition abcDetect.c:43
@ ABC_FIN_RDOB_AND
Definition abcDetect.c:40
@ ABC_FIN_RDOB_NXOR
Definition abcDetect.c:45
@ ABC_FIN_RDOB_BUFF
Definition abcDetect.c:47
@ ABC_FIN_NEG
Definition abcDetect.c:39
void Abc_NtkFinLocalSetdown(Vec_Int_t *vPairs, Vec_Int_t *vList, Vec_Wec_t *vMap2)
Definition abcDetect.c:960
int Abc_NtkDetectObjClasses_rec(Abc_Obj_t *pObj, Vec_Int_t *vMap, Hsh_VecMan_t *pHash, Vec_Int_t *vTemp)
Definition abcDetect.c:347
void Abc_NtkFinLocalSetup(Vec_Int_t *vPairs, Vec_Int_t *vList, Vec_Wec_t *vMap2, Vec_Int_t *vResArray)
Definition abcDetect.c:948
int Io_ReadFinType(char *pThis)
Definition abcDetect.c:121
Gia_Man_t * Abc_NtkFinMiterToGia(Abc_Ntk_t *pNtk, Vec_Int_t *vTypes, Vec_Int_t *vCos, Vec_Int_t *vCis, Vec_Int_t *vNodes, int iObjs[2], int Types[2], Vec_Int_t *vLits)
Definition abcDetect.c:728
Vec_Int_t * Abc_NtkFinCheckPair(Abc_Ntk_t *pNtk, Vec_Int_t *vTypes, Vec_Int_t *vCos, Vec_Int_t *vCis, Vec_Int_t *vNodes, int iObjs[2], int Types[2], Vec_Int_t *vLits)
Definition abcDetect.c:893
Vec_Int_t * Io_ReadFins(Abc_Ntk_t *pNtk, char *pFileName, int fVerbose)
Definition abcDetect.c:164
void Abc_NtkGenFaultList(Abc_Ntk_t *pNtk, char *pFileName, int fStuckAt)
FUNCTION DEFINITIONS ///.
Definition abcDetect.c:66
Vec_Wec_t * Abc_NtkDetectObjClasses(Abc_Ntk_t *pNtk, Vec_Int_t *vObjs, Vec_Wec_t **pvCos)
Definition abcDetect.c:391
int Abc_NtkFinRefinement(Abc_Ntk_t *pNtk, Vec_Int_t *vTypes, Vec_Int_t *vCos, Vec_Int_t *vCis, Vec_Int_t *vNodes, Vec_Int_t *vPairs, Vec_Int_t *vList, Vec_Wec_t *vMap2, Vec_Wec_t *vResult)
Definition abcDetect.c:970
void Abc_NtkFinSimulateOne(Abc_Ntk_t *pNtk, Vec_Int_t *vTypes, Vec_Int_t *vCos, Vec_Int_t *vCis, Vec_Int_t *vNodes, Vec_Wec_t *vMap2, Vec_Int_t *vPat, Vec_Wrd_t *vSims, int nWords, Vec_Int_t *vPairs, Vec_Wec_t *vRes, int iLevel, int iItem)
Definition abcDetect.c:783
int Mio_LibGateSimulateOne(Mio_Gate_t *pGate, int iBits[6])
Definition abcDetect.c:555
void Abc_NtkFrameExtend(Abc_Ntk_t *pNtk)
Definition abcDetect.c:264
Vec_Int_t * Abc_NtkFinComputeObjects(Vec_Int_t *vPairs, Vec_Wec_t **pvMap, int nObjs)
Definition abcDetect.c:1099
int Abc_NtkFinCountPairs(Vec_Wec_t *vClasses)
Definition abcDetect.c:1120
Vec_Int_t * Abc_NtkFinComputeTypes(Abc_Ntk_t *pNtk)
Definition abcDetect.c:1091
int Io_ReadFinTypeMapped(Mio_Library_t *pLib, char *pThis)
Definition abcDetect.c:111
void Mio_LibGateSimulate(Mio_Gate_t *pGate, word *ppFaninSims[6], int nWords, word *pObjSim)
Definition abcDetect.c:530
int Abc_NtkFinCheckTypesOk(Abc_Ntk_t *pNtk)
Definition abcDetect.c:1065
void Abc_NtkPrintFinResults(Vec_Wec_t *vClasses)
Definition abcDetect.c:1221
int Mio_LibGateSimulateGia(Gia_Man_t *pGia, Mio_Gate_t *pGate, int iLits[6], Vec_Int_t *vLits)
Definition abcDetect.c:576
Vec_Wec_t * Abc_NtkDetectFinClasses(Abc_Ntk_t *pNtk, int fVerbose)
Definition abcDetect.c:1128
void Abc_NtkFinMiterCollect(Abc_Ntk_t *pNtk, Vec_Int_t *vCos, Vec_Int_t *vCis, Vec_Int_t *vNodes)
Definition abcDetect.c:509
int Abc_NtkFinCheckTypesOk2(Abc_Ntk_t *pNtk)
Definition abcDetect.c:1073
int nWords
Definition abcNpn.c:127
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition abcFanio.c:84
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition abc.h:520
ABC_DLL Abc_Obj_t * Abc_NtkDupObj(Abc_Ntk_t *pNtkNew, Abc_Obj_t *pObj, int fCopyName)
Definition abcObj.c:342
#define Abc_NtkForEachObj(pNtk, pObj, i)
ITERATORS ///.
Definition abc.h:449
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeOr(Abc_Ntk_t *pNtk, Vec_Ptr_t *vFanins)
Definition abcObj.c:770
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition abcNames.c:69
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeAnd(Abc_Ntk_t *pNtk, Vec_Ptr_t *vFanins)
Definition abcObj.c:738
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeInv(Abc_Ntk_t *pNtk, Abc_Obj_t *pFanin)
Definition abcObj.c:674
#define Abc_NtkForEachPi(pNtk, pPi, i)
Definition abc.h:516
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition abc.h:518
ABC_DLL void Abc_ObjPatchFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFaninOld, Abc_Obj_t *pFaninNew)
Definition abcFanio.c:172
#define Abc_NtkForEachObjVec(vIds, pNtk, pObj, i)
Definition abc.h:455
#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_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
#define l_True
Definition bmcBmcS.c:35
#define l_Undef
Definition bmcBmcS.c:34
#define sat_solver
Definition cecSatG2.c:34
#define sat_solver_solve
Definition cecSatG2.c:45
struct Cnf_Dat_t_ Cnf_Dat_t
Definition cnf.h:52
void Cnf_DataFree(Cnf_Dat_t *p)
Definition cnfMan.c:207
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
void Gia_ManHashStart(Gia_Man_t *p)
Definition giaHash.c:125
Gia_Man_t * Gia_ManStart(int nObjsMax)
FUNCTION DEFINITIONS ///.
Definition giaMan.c:57
int Gia_ManHashOr(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:621
int Gia_ManHashXor(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:668
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
Gia_Man_t * Gia_ManCleanup(Gia_Man_t *p)
Definition giaScl.c:84
int Gia_ManHashAnd(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:576
void * Mf_ManGenerateCnf(Gia_Man_t *pGia, int nLutSize, int fCnfObjIds, int fAddOrCla, int fMapping, int fVerbose)
Definition giaMf.c:1877
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
int Mio_GateReadPinNum(Mio_Gate_t *pGate)
Definition mioApi.c:177
struct Mio_LibraryStruct_t_ Mio_Library_t
Definition mio.h:42
Vec_Int_t * Mio_GateReadExpr(Mio_Gate_t *pGate)
Definition mioApi.c:180
Mio_Gate_t * Mio_LibraryReadGateByName(Mio_Library_t *pLib, char *pName, char *pOutName)
Definition mioApi.c:105
#define Mio_LibraryForEachGate(Lib, Gate)
GLOBAL VARIABLES ///.
Definition mio.h:81
char * Mio_GateReadName(Mio_Gate_t *pGate)
Definition mioApi.c:169
Mio_Gate_t * Mio_LibraryReadGateById(Mio_Library_t *pLib, int iD)
Definition mioApi.c:48
struct Mio_GateStruct_t_ Mio_Gate_t
Definition mio.h:43
int Mio_GateReadCell(Mio_Gate_t *pGate)
Definition mioApi.c:184
word * Mio_GateReadTruthP(Mio_Gate_t *pGate)
Definition mioApi.c:182
void * Cnf_DataWriteIntoSolver(Cnf_Dat_t *p, int nFrames, int fInit)
Definition cnfMan.c:579
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
char * pName
Definition abc.h:158
int nConstrs
Definition abc.h:173
Vec_Int_t * vFins
Definition abc.h:216
void * pManFunc
Definition abc.h:191
char * pSpec
Definition abc.h:159
void * pData
Definition abc.h:145
Abc_Ntk_t * pNtk
Definition abc.h:130
Abc_Obj_t * pCopy
Definition abc.h:148
int nVars
Definition cnf.h:59
char * pSpec
Definition gia.h:100
char * pName
Definition gia.h:99
int Abc_NamStrFind(Abc_Nam_t *p, char *pStr)
Definition utilNam.c:433
int Abc_NamStrFindOrAdd(Abc_Nam_t *p, char *pStr, int *pfFound)
Definition utilNam.c:453
int Abc_NamObjNumMax(Abc_Nam_t *p)
Definition utilNam.c:231
Abc_Nam_t * Abc_NamStart(int nObjs, int nAveSize)
FUNCTION DEFINITIONS ///.
Definition utilNam.c:80
void Abc_NamDeref(Abc_Nam_t *p)
Definition utilNam.c:212
typedefABC_NAMESPACE_HEADER_START struct Abc_Nam_t_ Abc_Nam_t
INCLUDES ///.
Definition utilNam.h:39
#define assert(ex)
Definition util_old.h:213
int strcmp()
char * strtok()
struct Hsh_VecMan_t_ Hsh_VecMan_t
Definition vecHsh.h:85
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
Definition vecInt.h:72
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
Definition vecInt.h:56
#define Vec_IntForEachEntryDoubleStart(vVec, Entry1, Entry2, i, Start)
Definition vecInt.h:74
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
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition vecWec.h:55
#define Vec_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
Definition vecWec.h:59
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42
#define Vec_WecForEachLevelStop(vGlob, vVec, i, LevelStop)
Definition vecWec.h:61
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42