From b10f6bd89929f20c882a4c17c6101e57dd541853 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 27 Nov 2021 17:12:08 -0800 Subject: [PATCH 01/74] Bug fix in sweep (which happens to be a rare bug in Abc_NodeMinimumBase) (additional fix). --- src/base/abc/abcMinBase.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c index 3f441e993..991f65a43 100644 --- a/src/base/abc/abcMinBase.c +++ b/src/base/abc/abcMinBase.c @@ -113,6 +113,7 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) DdNode * bTemp, ** pbVars; Vec_Str_t * vSupport; int i, nVars, j, iFanin, iFanin2, k = 0; + int fDupFanins = 0; assert( Abc_NtkIsBddLogic(pNode->pNtk) ); assert( Abc_ObjIsNode(pNode) ); @@ -140,6 +141,7 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) Vec_IntForEachEntryStop( &pNode->vFanins, iFanin2, j, k ) if ( iFanin == iFanin2 ) break; + fDupFanins |= (int)(j < k); if ( j == k ) Vec_IntWriteEntry( &pNode->vFanins, k++, iFanin ); else if ( !Vec_IntRemove( &pFanin->vFanouts, pNode->Id ) ) @@ -153,6 +155,10 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) Cudd_RecursiveDeref( dd, bTemp ); Vec_StrFree( vSupport ); ABC_FREE( pbVars ); + + // try again if node had duplicated fanins + if ( fDupFanins ) + Abc_NodeMinimumBase( pNode ); return 1; } From f26ea1eaea5b51a3aec8107636c9f88eadfdcee0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 27 Nov 2021 17:37:34 -0800 Subject: [PATCH 02/74] Changes to make compiler happy. --- src/base/abci/abcNtbdd.c | 3 ++- src/bdd/cudd/cuddAddIte.c | 25 +++++++++++++++++++++ src/bdd/cudd/cuddAddNeg.c | 20 +++++++++++++++++ src/bdd/cudd/cuddBddAbs.c | 19 ++++++++++++++++ src/bdd/cudd/cuddBddIte.c | 24 ++++++++++++++++++++ src/bdd/cudd/cuddClip.c | 32 +++++++++++++++++++++++++++ src/bdd/cudd/cuddMatMult.c | 21 ++++++++++++++++++ src/bdd/cudd/cuddPriority.c | 24 ++++++++++++++++++++ src/bdd/cudd/cuddSat.c | 44 +++++++++++++++++++++++++++++++++++++ src/bdd/cudd/cuddZddIsop.c | 20 +++++++++++++++++ 10 files changed, 231 insertions(+), 1 deletion(-) diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index cbf4bbb8b..9de88980d 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -237,7 +237,8 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * { Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC; assert( !Cudd_IsComplement(bFunc) ); - if ( bFunc == b1 || bFunc == a1 ) + assert( b1 == a1 ); + if ( bFunc == a1 ) return Abc_NtkCreateNodeConst1(pNtkNew); if ( bFunc == a0 ) return Abc_NtkCreateNodeConst0(pNtkNew); diff --git a/src/bdd/cudd/cuddAddIte.c b/src/bdd/cudd/cuddAddIte.c index 574159c64..5f95bf47e 100644 --- a/src/bdd/cudd/cuddAddIte.c +++ b/src/bdd/cudd/cuddAddIte.c @@ -359,6 +359,22 @@ Cudd_addCmpl( } /* end of Cudd_addCmpl */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 as a key + that can be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_addLeq_dummy(DdManager * dd, DdNode * f, DdNode * g) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Determines whether f is less than or equal to g.] @@ -394,7 +410,11 @@ Cudd_addLeq( if (g == DD_MINUS_INFINITY(dd)) return(0); /* since f != g */ /* Check cache. */ +#ifdef USE_CASH_DUMMY + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq_dummy,f,g); +#else tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_addLeq,f,g); +#endif if (tmp != NULL) { return(tmp == DD_ONE(dd)); } @@ -416,8 +436,13 @@ Cudd_addLeq( res = Cudd_addLeq(dd,fvn,gvn) && Cudd_addLeq(dd,fv,gv); /* Store result in cache and return. */ +#ifdef USE_CASH_DUMMY + cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq_dummy,f,g, + Cudd_NotCond(DD_ONE(dd),res==0)); +#else cuddCacheInsert2(dd,(DD_CTFP) Cudd_addLeq,f,g, Cudd_NotCond(DD_ONE(dd),res==0)); +#endif return(res); } /* end of Cudd_addLeq */ diff --git a/src/bdd/cudd/cuddAddNeg.c b/src/bdd/cudd/cuddAddNeg.c index ab36874d2..22d112199 100644 --- a/src/bdd/cudd/cuddAddNeg.c +++ b/src/bdd/cudd/cuddAddNeg.c @@ -226,6 +226,22 @@ cuddAddNegateRecur( } /* end of cuddAddNegateRecur */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup1 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_addRoundOff_dummy(DdManager * dd, DdNode * f) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Implements the recursive step of Cudd_addRoundOff.] @@ -253,7 +269,11 @@ cuddAddRoundOffRecur( res = cuddUniqueConst(dd,n); return(res); } +#ifdef USE_CASH_DUMMY + cacheOp = (DD_CTFP1) Cudd_addRoundOff_dummy; +#else cacheOp = (DD_CTFP1) Cudd_addRoundOff; +#endif res = cuddCacheLookup1(dd,cacheOp,f); if (res != NULL) { return(res); diff --git a/src/bdd/cudd/cuddBddAbs.c b/src/bdd/cudd/cuddBddAbs.c index bfdd08bad..e2345617c 100644 --- a/src/bdd/cudd/cuddBddAbs.c +++ b/src/bdd/cudd/cuddBddAbs.c @@ -266,6 +266,21 @@ Cudd_bddBooleanDiff( } /* end of Cudd_bddBooleanDiff */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_bddVarIsDependent_dummy(DdManager *dd, DdNode *f, DdNode *var) +{ + assert(0); + return 0; +} +#endif + /**Function******************************************************************** Synopsis [Checks whether a variable is dependent on others in a @@ -305,7 +320,11 @@ Cudd_bddVarIsDependent( return(0); } +#ifdef USE_CASH_DUMMY + cacheOp = (DD_CTFP) Cudd_bddVarIsDependent_dummy; +#else cacheOp = (DD_CTFP) Cudd_bddVarIsDependent; +#endif res = cuddCacheLookup2(dd,cacheOp,f,var); if (res != NULL) { return(res != zero); diff --git a/src/bdd/cudd/cuddBddIte.c b/src/bdd/cudd/cuddBddIte.c index 803d5f191..2901096ca 100644 --- a/src/bdd/cudd/cuddBddIte.c +++ b/src/bdd/cudd/cuddBddIte.c @@ -520,6 +520,22 @@ Cudd_bddXnor( } /* end of Cudd_bddXnor */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_bddLeq_dummy(DdManager * dd, DdNode * f, DdNode * g) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Determines whether f is less than or equal to g.] @@ -573,7 +589,11 @@ Cudd_bddLeq( /* Here neither f nor g is constant. */ /* Check cache. */ +#ifdef USE_CASH_DUMMY + tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq_dummy,f,g); +#else tmp = cuddCacheLookup2(dd,(DD_CTFP)Cudd_bddLeq,f,g); +#endif if (tmp != NULL) { return(tmp == one); } @@ -605,7 +625,11 @@ Cudd_bddLeq( res = Cudd_bddLeq(dd,fvn,gvn) && Cudd_bddLeq(dd,fv,gv); /* Store result in cache and return. */ +#ifdef USE_CASH_DUMMY + cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq_dummy,f,g,(res ? one : zero)); +#else cuddCacheInsert2(dd,(DD_CTFP)Cudd_bddLeq,f,g,(res ? one : zero)); +#endif return(res); } /* end of Cudd_bddLeq */ diff --git a/src/bdd/cudd/cuddClip.c b/src/bdd/cudd/cuddClip.c index 9e3572f90..32ee7f6ee 100644 --- a/src/bdd/cudd/cuddClip.c +++ b/src/bdd/cudd/cuddClip.c @@ -250,6 +250,34 @@ cuddBddClippingAndAbstract( /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_bddClippingAnd_dummy(DdManager *dd, DdNode *f, DdNode *g) +{ + assert(0); + return 0; +} + + +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +cuddBddClippingAnd_dummy(DdManager *dd, DdNode *f, DdNode *g) +{ + assert(0); + return 0; +} +#endif /**Function******************************************************************** @@ -309,8 +337,12 @@ cuddBddClippingAndRecur( } F = Cudd_Regular(f); G = Cudd_Regular(g); +#ifdef USE_CASH_DUMMY + cacheOp = (DD_CTFP) (direction ? Cudd_bddClippingAnd_dummy : cuddBddClippingAnd_dummy); +#else cacheOp = (DD_CTFP) (direction ? Cudd_bddClippingAnd : cuddBddClippingAnd); +#endif if (F->ref != 1 || G->ref != 1) { r = cuddCacheLookup2(manager, cacheOp, f, g); if (r != NULL) return(r); diff --git a/src/bdd/cudd/cuddMatMult.c b/src/bdd/cudd/cuddMatMult.c index e8cae2cea..3dafa226e 100644 --- a/src/bdd/cudd/cuddMatMult.c +++ b/src/bdd/cudd/cuddMatMult.c @@ -319,6 +319,23 @@ Cudd_addOuterSum( /* Definition of static functions */ /*---------------------------------------------------------------------------*/ + +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +addMMRecur_dummy(DdManager * dd, DdNode * A, DdNode * B) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_addMatrixMultiply.] @@ -393,7 +410,11 @@ addMMRecur( topA = cuddI(dd,A->index); topB = cuddI(dd,B->index); topV = ddMin(topA,topB); +#ifdef USE_CASH_DUMMY + cacheOp = (DD_CTFP) addMMRecur_dummy; +#else cacheOp = (DD_CTFP) addMMRecur; +#endif res = cuddCacheLookup2(dd,cacheOp,A,B); if (res != NULL) { /* If the result is 0, there is no need to normalize. diff --git a/src/bdd/cudd/cuddPriority.c b/src/bdd/cudd/cuddPriority.c index aae5a7328..27da4dc6d 100644 --- a/src/bdd/cudd/cuddPriority.c +++ b/src/bdd/cudd/cuddPriority.c @@ -1571,6 +1571,22 @@ cuddCProjectionRecur( } /* end of cuddCProjectionRecur */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +DdNode * +Cudd_bddClosestCube_dummy(DdManager *dd, DdNode *f, DdNode *g) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_bddClosestCube.] @@ -1667,7 +1683,11 @@ cuddBddClosestCube( F = Cudd_Regular(f); G = Cudd_Regular(g); if (F->ref != 1 || G->ref != 1) { +#ifdef USE_CASH_DUMMY + res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube_dummy, f, g); +#else res = cuddCacheLookup2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g); +#endif if (res != NULL) return(res); } @@ -1817,7 +1837,11 @@ cuddBddClosestCube( /* Only cache results that are different from azero to avoid ** storing results that depend on the value of the bound. */ if ((F->ref != 1 || G->ref != 1) && res != azero) +#ifdef USE_CASH_DUMMY + cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube_dummy, f, g, res); +#else cuddCacheInsert2(dd,(DD_CTFP) Cudd_bddClosestCube, f, g, res); +#endif cuddDeref(res); return(res); diff --git a/src/bdd/cudd/cuddSat.c b/src/bdd/cudd/cuddSat.c index 899901dd2..976c59ab3 100644 --- a/src/bdd/cudd/cuddSat.c +++ b/src/bdd/cudd/cuddSat.c @@ -390,6 +390,22 @@ Cudd_ShortestLength( } /* end of Cudd_ShortestLength */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_Decreasing_dummy(DdManager * dd, DdNode * f, DdNode * g) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Determines whether a BDD is negative unate in a @@ -434,7 +450,11 @@ Cudd_Decreasing( /* From now on, f is not constant. */ /* Check cache. */ +#ifdef USE_CASH_DUMMY + cacheOp = (DD_CTFP) Cudd_Decreasing_dummy; +#else cacheOp = (DD_CTFP) Cudd_Decreasing; +#endif res = cuddCacheLookup2(dd,cacheOp,f,dd->vars[i]); if (res != NULL) { return(res); @@ -768,6 +788,22 @@ Cudd_bddLeqUnless( } /* end of Cudd_bddLeqUnless */ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +Cudd_EqualSupNorm_dummy(DdManager * dd, DdNode * f, DdNode * g) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Compares two ADDs for equality within tolerance.] @@ -817,7 +853,11 @@ Cudd_EqualSupNorm( /* We only insert the result in the cache if the comparison is ** successful. Therefore, if we hit we return 1. */ +#ifdef USE_CASH_DUMMY + r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm_dummy,f,g); +#else r = cuddCacheLookup2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g); +#endif if (r != NULL) { return(1); } @@ -832,7 +872,11 @@ Cudd_EqualSupNorm( if (!Cudd_EqualSupNorm(dd,fv,gv,tolerance,pr)) return(0); if (!Cudd_EqualSupNorm(dd,fvn,gvn,tolerance,pr)) return(0); +#ifdef USE_CASH_DUMMY + cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm_dummy,f,g,DD_ONE(dd)); +#else cuddCacheInsert2(dd,(DD_CTFP)Cudd_EqualSupNorm,f,g,DD_ONE(dd)); +#endif return(1); diff --git a/src/bdd/cudd/cuddZddIsop.c b/src/bdd/cudd/cuddZddIsop.c index ace0807bd..116b7c2ff 100644 --- a/src/bdd/cudd/cuddZddIsop.c +++ b/src/bdd/cudd/cuddZddIsop.c @@ -219,6 +219,22 @@ Cudd_MakeBddFromZddCover( /*---------------------------------------------------------------------------*/ +#ifdef USE_CASH_DUMMY +/**Function******************************************************************** + + Synopsis We need to declare a function passed to cuddCacheLookup2 that can + be casted to DD_CTFP. + +******************************************************************************/ +static DdNode * +cuddZddIsop_dummy(DdManager * dd, DdNode * L, DdNode * U) +{ + assert(0); + return 0; +} +#endif + + /**Function******************************************************************** Synopsis [Performs the recursive step of Cudd_zddIsop.] @@ -273,7 +289,11 @@ cuddZddIsop( ** Hence we need a double hit in the cache to terminate the ** recursion. Clearly, collisions may evict only one of the two ** results. */ +#ifdef USE_CASH_DUMMY + cacheOp = (DD_CTFP) cuddZddIsop_dummy; +#else cacheOp = (DD_CTFP) cuddZddIsop; +#endif r = cuddCacheLookup2(dd, cuddBddIsop, L, U); if (r) { *zdd_I = cuddCacheLookup2Zdd(dd, cacheOp, L, U); From dfa34cc2e4fe408f4ec6046ba9c0834fd2eaafb4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 30 Nov 2021 15:23:20 -0800 Subject: [PATCH 03/74] Disabling choices when they are computed incorrectly. --- src/base/abc/abcCheck.c | 5 ++++- src/base/abci/abcDar.c | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/base/abc/abcCheck.c b/src/base/abc/abcCheck.c index a7448530e..c492b7093 100644 --- a/src/base/abc/abcCheck.c +++ b/src/base/abc/abcCheck.c @@ -177,7 +177,10 @@ int Abc_NtkDoCheck( Abc_Ntk_t * pNtk ) // check the nodes if ( Abc_NtkIsStrash(pNtk) ) - Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc ); + { + if ( !Abc_AigCheck( (Abc_Aig_t *)pNtk->pManFunc ) ) + return 0; + } else { Abc_NtkForEachNode( pNtk, pNode, i ) diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 483f65b95..f68180102 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -1204,7 +1204,11 @@ Abc_Ntk_t * Abc_NtkFromDarChoices( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) Aig_ManForEachCo( pMan, pObj, i ) Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); if ( !Abc_NtkCheck( pNtkNew ) ) - Abc_Print( 1, "Abc_NtkFromDar(): Network check has failed.\n" ); + { + Abc_Print( 1, "Abc_NtkFromDar(): Network check has failed. Returning original network.\n" ); + Abc_NtkDelete( pNtkNew ); + pNtkNew = Abc_NtkDup( pNtkOld ); + } // verify topological order if ( 0 ) From 03b9f41786b59f90b1513e9436ec3e1082f80cb3 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Dec 2021 22:20:55 -0800 Subject: [PATCH 04/74] Bug fix in blasting word-level flops. --- src/aig/gia/giaSwitch.c | 8 ++++++++ src/base/wlc/wlcBlast.c | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/aig/gia/giaSwitch.c b/src/aig/gia/giaSwitch.c index b1c5eb823..4722ef0f5 100644 --- a/src/aig/gia/giaSwitch.c +++ b/src/aig/gia/giaSwitch.c @@ -795,6 +795,14 @@ float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbO Gia_ManForEachAnd( p, pObj, i ) SwiTotal += pSwi[Gia_ObjFaninId0(pObj, i)] + pSwi[Gia_ObjFaninId1(pObj, i)]; } + if ( 0 ) + { + Gia_ManForEachObj( p, pObj, i ) + { + printf( "Switch %6.2f ", pSwi[i] ); + Gia_ObjPrint( p, pObj ); + } + } Vec_IntFree( vSwitching ); return SwiTotal; } diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 6e910cd87..c6edb3aba 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -1930,9 +1930,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) // create combinational outputs in the normal manager pFans0 = Wlc_ObjFaninNum(pObj) > 0 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId0(pObj)) ) : NULL; - pFans1 = Wlc_ObjFaninNum(pObj) > 1 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId1(pObj)) ) : NULL; - pFans2 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId2(pObj)) ) : NULL; - pFans3 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; + pFans1 = Wlc_ObjFaninNum(pObj) > 2 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,2)) ) : NULL; // reset + pFans2 = Wlc_ObjFaninNum(pObj) > 3 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,3)) ) : NULL; // set + pFans3 = Wlc_ObjFaninNum(pObj) > 4 ? Vec_IntEntryP( vBits, Wlc_ObjCopy(p, Wlc_ObjFaninId(pObj,4)) ) : NULL; // enable for ( k = 0; k < nRange; k++ ) Gia_ManAppendCo( pNew, pFans0[k] ); Gia_ManAppendCo( pNew, pFans1[0] ); From b7176ee3e52c5068d93abd898be0639f9a648230 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Dec 2021 18:48:26 -0800 Subject: [PATCH 05/74] Adding command-line switch 'testnpn -A 12' for P-only canonical form computation. --- src/base/abci/abc.c | 1 + src/base/abci/abcNpn.c | 15 ++++++++++++++- src/opt/dau/dauCanon.c | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 29732bc6c..704790416 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -6961,6 +6961,7 @@ usage: Abc_Print( -2, "\t 9: adjustable algorithm (heuristic) by XueGong Zhou at Fudan University, Shanghai\n" ); Abc_Print( -2, "\t 10: adjustable algorithm (exact) by XueGong Zhou at Fudan University, Shanghai\n" ); Abc_Print( -2, "\t 11: new cost-aware exact algorithm by XueGong Zhou at Fudan University, Shanghai\n" ); + Abc_Print( -2, "\t 12: new fast hybrid semi-canonical form (permutation only)\n" ); Abc_Print( -2, "\t-N : the number of support variables (binary files only) [default = unused]\n" ); Abc_Print( -2, "\t-d : toggle dumping resulting functions into a file [default = %s]\n", fDumpRes? "yes": "no" ); Abc_Print( -2, "\t-b : toggle dumping in binary format [default = %s]\n", fBinary? "yes": "no" ); diff --git a/src/base/abci/abcNpn.c b/src/base/abci/abcNpn.c index e109a9cff..92b47c177 100644 --- a/src/base/abci/abcNpn.c +++ b/src/base/abci/abcNpn.c @@ -208,6 +208,8 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) pAlgoName = "adjustable algorithm (exact) "; else if ( NpnType == 11 ) pAlgoName = "new cost-aware exact algorithm "; + else if ( NpnType == 12 ) + pAlgoName = "new hybrid fast (P) "; assert( p->nVars <= 16 ); if ( pAlgoName ) @@ -356,6 +358,17 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose ) } Abc_TtHieManStop(pMan); } + else if ( NpnType == 12 ) + { + for ( i = 0; i < p->nFuncs; i++ ) + { + if ( fVerbose ) + printf( "%7d : ", i ); + uCanonPhase = Abc_TtCanonicizePerm( p->pFuncs[i], p->nVars, pCanonPerm ); + if ( fVerbose ) + Extra_PrintHex( stdout, (unsigned *)p->pFuncs[i], p->nVars ), Abc_TruthNpnPrint(pCanonPerm, uCanonPhase, p->nVars), printf( "\n" ); + } + } else assert( 0 ); clk = Abc_Clock() - clk; printf( "Classes =%9d ", Abc_TruthNpnCountUnique(p) ); @@ -419,7 +432,7 @@ int Abc_NpnTest( char * pFileName, int NpnType, int nVarNum, int fDumpRes, int f { if ( fVerbose ) printf( "Using truth tables from file \"%s\"...\n", pFileName ); - if ( NpnType >= 0 && NpnType <= 11 ) + if ( NpnType >= 0 && NpnType <= 12 ) Abc_TruthNpnTest( pFileName, NpnType, nVarNum, fDumpRes, fBinary, fVerbose ); else printf( "Unknown canonical form value (%d).\n", NpnType ); diff --git a/src/opt/dau/dauCanon.c b/src/opt/dau/dauCanon.c index 89359611e..dd954d9a7 100644 --- a/src/opt/dau/dauCanon.c +++ b/src/opt/dau/dauCanon.c @@ -1027,7 +1027,7 @@ int Abc_TtCofactorPerm( word * pTruth, int i, int nWords, int fSwapOnly, char * SeeAlso [] ***********************************************************************/ -#define CANON_VERIFY +//#define CANON_VERIFY unsigned Abc_TtCanonicize( word * pTruth, int nVars, char * pCanonPerm ) { int pStoreIn[17]; From 8e72ac36d718cd0dc27f181dfa10746ad4a101ed Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Dec 2021 13:38:09 -0800 Subject: [PATCH 06/74] Outputting the constant node in 'write_gml'. --- src/base/io/ioWriteGml.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/base/io/ioWriteGml.c b/src/base/io/ioWriteGml.c index 49a90d9c1..1164188f3 100644 --- a/src/base/io/ioWriteGml.c +++ b/src/base/io/ioWriteGml.c @@ -61,6 +61,18 @@ void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ) fprintf( pFile, "# GML for \"%s\" written by ABC on %s\n", pNtk->pName, Extra_TimeStamp() ); fprintf( pFile, "graph [\n" ); + // output constant node in the AIG if it has fanouts + if ( Abc_NtkIsStrash(pNtk) ) + { + pObj = Abc_AigConst1( pNtk ); + if ( Abc_ObjFanoutNum(pObj) > 0 ) + { + fprintf( pFile, "\n" ); + fprintf( pFile, " node [ id %5d label \"%s\"\n", pObj->Id, Abc_ObjName(pObj) ); + fprintf( pFile, " graphics [ type \"ellipse\" fill \"#CCCCFF\" ]\n" ); // grey + fprintf( pFile, " ]\n" ); + } + } // output the POs fprintf( pFile, "\n" ); Abc_NtkForEachPo( pNtk, pObj, i ) From fb248e1ca1881e85abda65dafa143436d05035c6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Dec 2021 11:30:06 +0700 Subject: [PATCH 07/74] Adding new command %yosys. --- abclib.dsp | 4 + src/base/wlc/wlcCom.c | 120 ++++++++++++++++++++++++++++ src/base/wln/module.make | 1 + src/base/wln/wlnRtl.c | 163 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 288 insertions(+) create mode 100644 src/base/wln/wlnRtl.c diff --git a/abclib.dsp b/abclib.dsp index 43b46871b..6878f78f6 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1147,6 +1147,10 @@ SOURCE=.\src\base\wln\wlnRetime.c # End Source File # Begin Source File +SOURCE=.\src\base\wln\wlnRtl.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wln\wlnWlc.c # End Source File # Begin Source File diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 39f1bebd1..b6456ba45 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,6 +32,7 @@ ABC_NAMESPACE_IMPL_START static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -79,6 +80,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) { Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); @@ -295,6 +297,124 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fVerbose ); + extern Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ); + + FILE * pFile; + char * pFileName = NULL; + char * pTopModule= NULL; + int fCollapse = 0; + int fBlast = 0; + int fInvert = 0; + int fSkipStrash = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Tcaisvh" ) ) != EOF ) + { + switch ( c ) + { + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); + goto usage; + } + pTopModule = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'c': + fCollapse ^= 1; + break; + case 'a': + fBlast ^= 1; + break; + case 'i': + fInvert ^= 1; + break; + case 's': + fSkipStrash ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); + return 0; + } + // get the file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) + { + Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); + if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + + // perform reading + if ( fBlast ) + { + Gia_Man_t * pNew = NULL; + if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fVerbose ); + else + { + printf( "Abc_CommandYosys(): Unknown file extension.\n" ); + return 0; + } + Abc_FrameUpdateGia( pAbc, pNew ); + } + else + { + Wln_Ntk_t * pNtk = NULL; + if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) + pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose ); + else + { + printf( "Abc_CommandYosys(): Unknown file extension.\n" ); + return 0; + } + //Wlc_AbcUpdateNtk( pAbc, pNtk ); + } + return 0; +usage: + Abc_Print( -2, "usage: %%yosys [-T ] [-caisvh] \n" ); + Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); + Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); + Abc_Print( -2, "\t-c : toggle collapsing the design using Yosys [default = %s]\n", fCollapse? "yes": "no" ); + Abc_Print( -2, "\t-a : toggle bit-blasting the design using Yosys [default = %s]\n", fBlast? "yes": "no" ); + Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} /**Function******************************************************************** diff --git a/src/base/wln/module.make b/src/base/wln/module.make index 748c104c0..308f76890 100644 --- a/src/base/wln/module.make +++ b/src/base/wln/module.make @@ -4,5 +4,6 @@ SRC += src/base/wln/wln.c \ src/base/wln/wlnNtk.c \ src/base/wln/wlnObj.c \ src/base/wln/wlnRetime.c \ + src/base/wln/wlnRtl.c \ src/base/wln/wlnWlc.c \ src/base/wln/wlnWriteVer.c diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c new file mode 100644 index 000000000..90fc768e0 --- /dev/null +++ b/src/base/wln/wlnRtl.c @@ -0,0 +1,163 @@ +/**CFile**************************************************************** + + FileName [wlnRtl.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [Constructing WLN network from Rtl data structure.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnRtl.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Wln_Ntk_t * Wln_ReadRtl( char * pFileName ) +{ + return NULL; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +char * Wln_GetYosysName() +{ + char * pYosysName = NULL; + char * pYosysNameWin = "yosys.exe"; + char * pYosysNameUnix = "yosys"; + if ( Abc_FrameReadFlag("yosyswin") ) + pYosysNameWin = Abc_FrameReadFlag("yosyswin"); + if ( Abc_FrameReadFlag("yosysunix") ) + pYosysNameUnix = Abc_FrameReadFlag("yosysunix"); +#ifdef WIN32 + pYosysName = pYosysNameWin; +#else + pYosysName = pYosysNameUnix; +#endif + return pYosysName; +} +int Wln_ConvertToRtl( char * pCommand, char * pFileTemp ) +{ + FILE * pFile; + if ( system( pCommand ) == -1 ) + { + fprintf( stdout, "Cannot execute \"%s\".\n", pCommand ); + return 0; + } + if ( (pFile = fopen(pFileTemp, "r")) == NULL ) + { + fprintf( stdout, "Cannot open intermediate file \"%s\".\n", pFileTemp ); + return 0; + } + fclose( pFile ); + return 1; +} +Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ) +{ + Wln_Ntk_t * pNtk = NULL; + char Command[1000]; + char * pFileTemp = "_temp_.rtlil"; + int fSVlog = strstr(pFileName, ".sv") != NULL; + sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; write_rtlil %s\"", + Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName, + pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", pFileTemp ); + if ( fVerbose ) + printf( "%s\n", Command ); + if ( !Wln_ConvertToRtl(Command, pFileTemp) ) + { + return NULL; + } + pNtk = Wln_ReadRtl( pFileTemp ); + if ( pNtk == NULL ) + { + printf( "Dumped the design into file \"%s\".\n", pFileTemp ); + return NULL; + } +#ifdef WIN32 + _unlink( pFileTemp ); +#else + unlink( pFileTemp ); +#endif + return pNtk; +} +Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fVerbose ) +{ + Gia_Man_t * pGia = NULL; + char Command[1000]; + char * pFileTemp = "_temp_.aig"; + int fSVlog = strstr(pFileName, ".sv") != NULL; + sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; aigmap; write_aiger %s\"", + Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName, + pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", pFileTemp ); + if ( fVerbose ) + printf( "%s\n", Command ); + if ( !Wln_ConvertToRtl(Command, pFileTemp) ) + return NULL; + pGia = Gia_AigerRead( pFileTemp, 0, fSkipStrash, 0 ); + if ( pGia == NULL ) + { + printf( "Converting to AIG has failed.\n" ); + return NULL; + } + ABC_FREE( pGia->pName ); + pGia->pName = pTopModule ? Abc_UtilStrsav(pTopModule) : + Extra_FileNameGeneric( Extra_FileNameWithoutPath(pFileName) ); +#ifdef WIN32 + _unlink( pFileTemp ); +#else + unlink( pFileTemp ); +#endif + // complement the outputs + if ( fInvert ) + { + Gia_Obj_t * pObj; int i; + Gia_ManForEachPo( pGia, pObj, i ) + Gia_ObjFlipFaninC0( pObj ); + } + return pGia; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + From f1b64be84071a431eac9871f8cdc71bc912fd75a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Dec 2021 11:32:53 +0700 Subject: [PATCH 08/74] Compiler warning. --- src/base/wln/wlnRtl.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index 90fc768e0..040c74bbd 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -21,6 +21,13 @@ #include "wln.h" #include "base/main/main.h" +#ifdef WIN32 +#include +#define unlink _unlink +#else +#include +#endif + ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// @@ -110,11 +117,7 @@ Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVer printf( "Dumped the design into file \"%s\".\n", pFileTemp ); return NULL; } -#ifdef WIN32 - _unlink( pFileTemp ); -#else unlink( pFileTemp ); -#endif return pNtk; } Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fVerbose ) @@ -139,11 +142,7 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSk ABC_FREE( pGia->pName ); pGia->pName = pTopModule ? Abc_UtilStrsav(pTopModule) : Extra_FileNameGeneric( Extra_FileNameWithoutPath(pFileName) ); -#ifdef WIN32 - _unlink( pFileTemp ); -#else unlink( pFileTemp ); -#endif // complement the outputs if ( fInvert ) { From 25b1a0d81c113bca545fd3b2f477e07e1d33e509 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Dec 2021 21:31:09 +0700 Subject: [PATCH 09/74] Fixing a rare problem with choice nodes. --- src/aig/gia/giaAig.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/aig/gia/giaAig.c b/src/aig/gia/giaAig.c index 91a9c6003..c764a0993 100644 --- a/src/aig/gia/giaAig.c +++ b/src/aig/gia/giaAig.c @@ -611,6 +611,27 @@ Gia_Man_t * Gia_ManCompress2( Gia_Man_t * p, int fUpdateLevel, int fVerbose ) SeeAlso [] ***********************************************************************/ +int Gia_ManTestChoices( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj; int i; + Vec_Int_t * vPointed = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_ManForEachAnd( p, pObj, i ) + if ( Gia_ObjSibl(p, i) ) + Vec_IntWriteEntry( vPointed, Gia_ObjSibl(p, i), 1 ); + Gia_ManCreateRefs( p ); + Gia_ManForEachAnd( p, pObj, i ) + if ( Vec_IntEntry(vPointed, i) && Gia_ObjRefNumId(p, i) > 0 ) + { + printf( "Gia_ManCheckChoices: Member %d", i ); + printf( " of a choice node has %d fanouts.\n", Gia_ObjRefNumId(p, i) ); + ABC_FREE( p->pRefs ); + Vec_IntFree( vPointed ); + return 0; + } + ABC_FREE( p->pRefs ); + Vec_IntFree( vPointed ); + return 1; +} Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) { int fUseMapping = 0; @@ -628,6 +649,11 @@ Gia_Man_t * Gia_ManPerformDch( Gia_Man_t * p, void * pPars ) // pGia = Gia_ManFromAig( pNew ); pGia = Gia_ManFromAigChoices( pNew ); Aig_ManStop( pNew ); + if ( !p->pManTime && !Gia_ManTestChoices(pGia) ) + { + Gia_ManStop( pGia ); + pGia = Gia_ManDup( p ); + } Gia_ManTransferTiming( pGia, p ); return pGia; } From 85b74f68f19fc4857daba703f909a02410f04065 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 17 Dec 2021 10:15:57 +0700 Subject: [PATCH 10/74] Adding new command &icec. --- src/aig/gia/gia.h | 1 + src/aig/gia/giaDup.c | 64 +++++++++++++++ src/base/abci/abc.c | 187 ++++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 15 ++-- src/base/wln/wlnRtl.c | 6 +- 5 files changed, 265 insertions(+), 8 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 5548def6b..d871905c8 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1351,6 +1351,7 @@ extern Gia_Man_t * Gia_ManPermuteInputs( Gia_Man_t * p, int nPpis, int n extern Gia_Man_t * Gia_ManDupDfsClasses( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupTopAnd( Gia_Man_t * p, int fVerbose ); extern Gia_Man_t * Gia_ManMiter( Gia_Man_t * pAig0, Gia_Man_t * pAig1, int nInsDup, int fDualOut, int fSeq, int fImplic, int fVerbose ); +extern Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOut, int fVerbose ); extern Gia_Man_t * Gia_ManDupAndOr( Gia_Man_t * p, int nOuts, int fUseOr, int fCompl ); extern Gia_Man_t * Gia_ManDupZeroUndc( Gia_Man_t * p, char * pInit, int nNewPis, int fGiaSimple, int fVerbose ); extern Gia_Man_t * Gia_ManMiter2( Gia_Man_t * p, char * pInit, int fVerbose ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index b3fcd295a..da4881cdd 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -2932,6 +2932,70 @@ Gia_Man_t * Gia_ManMiter( Gia_Man_t * p0, Gia_Man_t * p1, int nInsDup, int fDual return pNew; } +/**Function************************************************************* + + Synopsis [Creates miter of two designs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOut, int fVerbose ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, iLit; + int nInputs1 = Gia_ManCiNum(pTop) - Gia_ManCoNum(pBot); + int nInputs2 = Gia_ManCiNum(pBot) - Gia_ManCoNum(pTop); + if ( nInputs1 == nInputs2 ) + printf( "Assuming that the circuits have %d shared inputs, ordered first.\n", nInputs1 ); + else + { + printf( "The number of inputs and outputs does not match.\n" ); + return NULL; + } + pNew = Gia_ManStart( Gia_ManObjNum(pBot) + Gia_ManObjNum(pTop) ); + pNew->pName = Abc_UtilStrsav( "miter" ); + Gia_ManFillValue( pBot ); + Gia_ManFillValue( pTop ); + Gia_ManConst0(pBot)->Value = 0; + Gia_ManConst0(pTop)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCi( pBot, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachCo( pBot, pObj, i ) + Gia_ManMiter_rec( pNew, pBot, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( pBot, pObj, i ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + Gia_ManForEachCi( pTop, pObj, i ) + if ( i < nInputs1 ) + pObj->Value = Gia_ManCi(pBot, i)->Value; + else + pObj->Value = Gia_ManCo(pBot, i-nInputs1)->Value; + Gia_ManForEachCo( pTop, pObj, i ) + Gia_ManMiter_rec( pNew, pTop, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCo( pTop, pObj, i ) + { + if ( fDualOut ) + { + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManAppendCo( pNew, Gia_ManCi(pBot, i+nInputs1)->Value ); + } + else + { + iLit = Gia_ManHashXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ManCi(pBot, i+nInputs1)->Value ); + Gia_ManAppendCo( pNew, iLit ); + } + } + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + /**Function************************************************************* Synopsis [Computes the AND of all POs.] diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 704790416..1d97f5e41 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -469,6 +469,7 @@ static int Abc_CommandAbc9Reduce ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9EquivMark ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9EquivFilter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cec ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9ICec ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Verify ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Force ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1212,6 +1213,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&equiv_mark", Abc_CommandAbc9EquivMark, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&equiv_filter", Abc_CommandAbc9EquivFilter, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cec", Abc_CommandAbc9Cec, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&icec", Abc_CommandAbc9ICec, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&verify", Abc_CommandAbc9Verify, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&sweep", Abc_CommandAbc9Sweep, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&force", Abc_CommandAbc9Force, 0 ); @@ -37939,6 +37941,191 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9ICec( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + FILE * pFile; + Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; + char ** pArgvNew; + int c, nArgcNew, fUseNew = 0, fDumpMiter = 0; + Cec_ManCecSetDefaultParams( pPars ); + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CTaxvwh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nBTLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nBTLimit < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + pPars->TimeLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->TimeLimit < 0 ) + goto usage; + break; + case 'a': + fDumpMiter ^= 1; + break; + case 'x': + fUseNew ^= 1; + break; + case 'v': + pPars->fVerbose ^= 1; + break; + case 'w': + pPars->fVeryVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew > 2 ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): Wrong number of command-line arguments.\n" ); + return 1; + } + if ( nArgcNew == 2 ) + { + char * pFileNames[2] = { pArgvNew[0], pArgvNew[1] }, * pTemp; + int n; + for ( n = 0; n < 2; n++ ) + { + // fix the wrong symbol + for ( pTemp = pFileNames[n]; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( pFileNames[n], "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", pFileNames[n] ); + if ( (pFileNames[n] = Extra_FileGetSimilarName( pFileNames[n], ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileNames[n] ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[n] = Gia_AigerRead( pFileNames[n], 0, 0, 0 ); + if ( pGias[n] == NULL ) + { + Abc_Print( -1, "Reading AIGER from file \"%s\" has failed.\n", pFileNames[n] ); + return 0; + } + } + } + else + { + char * FileName, * pTemp; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Cec(): There is no current AIG.\n" ); + return 1; + } + pGias[0] = pAbc->pGia; + if ( nArgcNew == 1 ) + FileName = pArgvNew[0]; + else + { + assert( nArgcNew == 0 ); + if ( pAbc->pGia->pSpec == NULL ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + FileName = pAbc->pGia->pSpec; + } + // fix the wrong symbol + for ( pTemp = FileName; *pTemp; pTemp++ ) + if ( *pTemp == '>' ) + *pTemp = '\\'; + if ( (pFile = fopen( FileName, "r" )) == NULL ) + { + Abc_Print( -1, "Cannot open input file \"%s\". ", FileName ); + if ( (FileName = Extra_FileGetSimilarName( FileName, ".aig", NULL, NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", FileName ); + Abc_Print( 1, "\n" ); + return 1; + } + fclose( pFile ); + pGias[1] = Gia_AigerRead( FileName, 0, 0, 0 ); + if ( pGias[1] == NULL ) + { + Abc_Print( -1, "Reading AIGER has failed.\n" ); + return 0; + } + } + // compute the miter + pMiter = Gia_ManMiterInverse( pGias[0], pGias[1], !fUseNew, pPars->fVerbose ); + if ( pMiter ) + { + if ( fDumpMiter ) + { + Abc_Print( 0, "The verification miter is written into file \"%s\".\n", "cec_miter.aig" ); + Gia_AigerWrite( pMiter, "cec_miter.aig", 0, 0, 0 ); + } + if ( fUseNew ) + { + abctime clk = Abc_Clock(); + extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_ManStop( pNew ); + } + else + { + pAbc->Status = Cec_ManVerify( pMiter, pPars ); + Abc_FrameReplaceCex( pAbc, &pGias[0]->pCexComb ); + } + Gia_ManStop( pMiter ); + } + if ( pGias[0] != pAbc->pGia ) + Gia_ManStop( pGias[0] ); + Gia_ManStop( pGias[1] ); + return 0; + +usage: + Abc_Print( -2, "usage: &icec [-CT num] [-axvwh]\n" ); + Abc_Print( -2, "\t combinational equivalence checker for inverse circuits\n" ); + Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); + Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); + Abc_Print( -2, "\t-a : toggle writing the miter [default = %s]\n", fDumpMiter? "yes":"no"); + Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no"); + Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); + Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no"); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index b6456ba45..b1573e731 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -310,7 +310,7 @@ usage: ******************************************************************************/ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fVerbose ); + extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); extern Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ); FILE * pFile; @@ -319,10 +319,11 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) int fCollapse = 0; int fBlast = 0; int fInvert = 0; + int fTechMap = 0; int fSkipStrash = 0; int c, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Tcaisvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Tcaismvh" ) ) != EOF ) { switch ( c ) { @@ -347,6 +348,9 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSkipStrash ^= 1; break; + case 'm': + fTechMap ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -378,9 +382,9 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pNew = NULL; if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fVerbose ); + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fVerbose ); + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); else { printf( "Abc_CommandYosys(): Unknown file extension.\n" ); @@ -404,13 +408,14 @@ int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) } return 0; usage: - Abc_Print( -2, "usage: %%yosys [-T ] [-caisvh] \n" ); + Abc_Print( -2, "usage: %%yosys [-T ] [-caismvh] \n" ); Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); Abc_Print( -2, "\t-c : toggle collapsing the design using Yosys [default = %s]\n", fCollapse? "yes": "no" ); Abc_Print( -2, "\t-a : toggle bit-blasting the design using Yosys [default = %s]\n", fBlast? "yes": "no" ); Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); + Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index 040c74bbd..aff88af99 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -120,15 +120,15 @@ Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVer unlink( pFileTemp ); return pNtk; } -Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fVerbose ) +Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ) { Gia_Man_t * pGia = NULL; char Command[1000]; char * pFileTemp = "_temp_.aig"; int fSVlog = strstr(pFileName, ".sv") != NULL; - sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; aigmap; write_aiger %s\"", + sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"", Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName, - pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", pFileTemp ); + pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", fTechMap ? "techmap; setundef -zero; " : "", pFileTemp ); if ( fVerbose ) printf( "%s\n", Command ); if ( !Wln_ConvertToRtl(Command, pFileTemp) ) From f288c4d7f6e97146bdc4de48f14168cbce9d3c96 Mon Sep 17 00:00:00 2001 From: QuantamHD Date: Mon, 20 Dec 2021 12:55:11 -0800 Subject: [PATCH 11/74] Fixes internal pin parsing error in ASAP7 liberty file. This fix addresses an issue I saw with the ASAP7 liberty files and ABC. ASAP7 lists internal pins in its liberty file which ABC's liberty parser doesn't account for. This causes an assert to be triggered. This fix simply adds interal pins to the ignore list. --- src/map/scl/sclLiberty.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 4b6adab48..49b5c2370 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -955,6 +955,8 @@ int Scl_LibertyReadPinDirection( Scl_Tree_t * p, Scl_Item_t * pPin ) return 0; if ( !strcmp(pToken, "output") ) return 1; + if ( !strcmp(pToken, "internal") ) + return 2; break; } return -1; @@ -1525,7 +1527,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos float CapOne, CapRise, CapFall; if ( Scl_LibertyReadPinFormula(p, pPin) != NULL ) // skip output pin continue; - assert( Scl_LibertyReadPinDirection(p, pPin) == 0 ); + assert( Scl_LibertyReadPinDirection(p, pPin) == 0 || Scl_LibertyReadPinDirection(p, pPin) == 2); pName = Scl_LibertyReadString(p, pPin->Head); Vec_PtrPush( vNameIns, Abc_UtilStrsav(pName) ); Vec_StrPutS_( vOut, pName ); @@ -1546,6 +1548,8 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos { if ( !Scl_LibertyReadPinFormula(p, pPin) ) // skip input pin continue; + if (Scl_LibertyReadPinDirection(p, pPin) == 2) // skip internal pin + continue; assert( Scl_LibertyReadPinDirection(p, pPin) == 1 ); pName = Scl_LibertyReadString(p, pPin->Head); Vec_StrPutS_( vOut, pName ); From 491e0e833f9e4037c296a75c88c1aeea00da1e5c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Dec 2021 17:57:41 +0700 Subject: [PATCH 12/74] Changes to pattern generation. --- src/aig/gia/giaPat2.c | 99 ++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 34 deletions(-) diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index f14ce34a3..f2cdfe792 100644 --- a/src/aig/gia/giaPat2.c +++ b/src/aig/gia/giaPat2.c @@ -890,6 +890,8 @@ int Min_ManCountSize( Vec_Wec_t * vCexes, int iFirst, int iLimit ) } Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTries, int nMinCexes, Vec_Int_t * vStats[3], int fUseSim, int fUseSat, int fVerbose ) { + int fUseSynthesis = 1; + abctime clkSim = Abc_Clock(), clkSat = Abc_Clock(); Vec_Int_t * vOuts = vOuts0 ? vOuts0 : Vec_IntStartNatural( Gia_ManCoNum(p) ); Min_Man_t * pNew = Min_ManFromGia( p, vOuts ); Vec_Wec_t * vCexes = Vec_WecStart( Vec_IntSize(vOuts) * nMinCexes ); @@ -945,6 +947,7 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[0]) ); assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[1]) ); assert( Vec_IntSize(vOuts) == Vec_IntSize(vStats[2]) ); + clkSim = Abc_Clock() - clkSim; if ( fUseSat ) Gia_ManForEachCoVec( vOuts, p, pObj, i ) @@ -952,11 +955,13 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) ) continue; { + abctime clk = Abc_Clock(); int iObj = Min_ManCo(pNew, i); int Index = Gia_ObjCioId(pObj); Vec_Int_t * vMap = Vec_IntAlloc( 100 ); Gia_Man_t * pCon = Gia_ManDupCones2( p, &Index, 1, vMap ); - Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCon, 8, 0, 0, 0, 0 ); + Gia_Man_t * pCon1= fUseSynthesis ? Gia_ManAigSyn2( pCon, 0, 1, 0, 100, 0, 0, 0 ) : NULL; + Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( fUseSynthesis ? pCon1 : pCon, 8, 0, 0, 0, 0 ); sat_solver* pSat = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 ); int Lit = Abc_Var2Lit( 1, 0 ); int status = sat_solver_addclause( pSat, &Lit, &Lit+1 ); @@ -972,8 +977,11 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie while ( nAllCalls++ < 100 ) { int v, iVar = pCnf->nVars - Gia_ManPiNum(pCon), nVars = Gia_ManPiNum(pCon); - sat_solver_randomize( pSat, iVar, nVars ); + if ( nAllCalls > 1 ) + sat_solver_randomize( pSat, iVar, nVars ); status = sat_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 ); + if ( status != l_True ) + break; assert( status == l_True ); Vec_IntClear( vLits ); for ( v = 0; v < nVars; v++ ) @@ -1004,11 +1012,22 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie sat_solver_delete( pSat ); Cnf_DataFree( pCnf ); Gia_ManStop( pCon ); + Gia_ManStopP( &pCon1 ); Vec_IntFree( vMap ); + if ( fVerbose ) + { + printf( "SAT solving for output %3d (cexes = %5d) : ", i, nCurrCexes ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } } } + clkSat = Abc_Clock() - clkSat - clkSim; if ( fVerbose ) printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts ); + if ( fVerbose ) + Abc_PrintTime( 1, "Simulation time ", clkSim ); + if ( fVerbose ) + Abc_PrintTime( 1, "SAT solving time", clkSat ); //Vec_WecPrint( vCexes, 0 ); if ( vOuts != vOuts0 ) Vec_IntFreeP( &vOuts ); @@ -1076,7 +1095,7 @@ Vec_Ptr_t * Min_ReloadCexes( Vec_Wec_t * vCexes, int nMinCexes ) Vec_Wrd_t * Min_ManBitPack( Gia_Man_t * p, int nWords0, Vec_Wec_t * vCexes, int fRandom, int nMinCexes, Vec_Int_t * vScores, int fVerbose ) { abctime clk = Abc_Clock(); - int fVeryVerbose = 0; + //int fVeryVerbose = 0; Vec_Wrd_t * vSimsPi = NULL; Vec_Int_t * vLevel; int w, nBits, nTotal = 0, fFailed = ABC_INFINITY; @@ -1259,39 +1278,51 @@ Vec_Wrd_t * Gia_ManCollectSims( Gia_Man_t * pSwp, int nWords, Vec_Int_t * vOuts, Vec_Int_t * vMap = Vec_IntAlloc( 100 ); Gia_Man_t * pSwp2 = Gia_ManDupCones2( pSwp, Vec_IntArray(vOuts), Vec_IntSize(vOuts), vMap ); Vec_Wec_t * vCexes = Min_ManComputeCexes( pSwp2, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose ); - Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose ); - Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 ); - Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) ); - if ( fVerbose ) - Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) ); - if ( fVeryVerbose ) + if ( Vec_IntSum(vStats[2]) == 0 ) { - printf( "Unsolved = %4d ", Vec_IntSize(vOuts) ); - Gia_ManPrintStats( pSwp2, NULL ); - Vec_IntForEachEntry( vOuts, iObj, i ) - { - printf( "%4d : ", i ); - printf( "Out = %5d ", Vec_IntEntry(vMap, i) ); - printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) ); - printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) ); - printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) ); - printf( "Count = %5d ", Vec_IntEntry(vCounts, i) ); - printf( "\n" ); - if ( i == 20 ) - break; - } + for ( i = 0; i < 3; i++ ) + Vec_IntFree( vStats[i] ); + Vec_IntFree( vMap ); + Gia_ManStop( pSwp2 ); + Vec_WecFree( vCexes ); + return NULL; + } + else + { + Vec_Wrd_t * vSimsPi = Min_ManBitPack( pSwp2, nWords, vCexes, 1, nMinCexes, vStats[0], fVerbose ); + Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( pSwp2, vSimsPi, 1 ); + Vec_Int_t * vCounts = Patt_ManOutputErrorCoverage( vSimsPo, Vec_IntSize(vOuts) ); + if ( fVerbose ) + Patt_ManProfileErrorsOne( vSimsPo, Vec_IntSize(vOuts) ); + if ( fVeryVerbose ) + { + printf( "Unsolved = %4d ", Vec_IntSize(vOuts) ); + Gia_ManPrintStats( pSwp2, NULL ); + Vec_IntForEachEntry( vOuts, iObj, i ) + { + printf( "%4d : ", i ); + printf( "Out = %5d ", Vec_IntEntry(vMap, i) ); + printf( "SimAll =%8d ", Vec_IntEntry(vStats[0], i) ); + printf( "SimGood =%8d ", Vec_IntEntry(vStats[1], i) ); + printf( "PatsAll =%8d ", Vec_IntEntry(vStats[2], i) ); + printf( "Count = %5d ", Vec_IntEntry(vCounts, i) ); + printf( "\n" ); + if ( i == 20 ) + break; + } + } + for ( i = 0; i < 3; i++ ) + Vec_IntFree( vStats[i] ); + Vec_IntFree( vCounts ); + Vec_WrdFree( vSimsPo ); + Vec_WecFree( vCexes ); + Gia_ManStop( pSwp2 ); + //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) ); + vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi ); + Vec_WrdFree( vSimsPo ); + Vec_IntFree( vMap ); + return vSimsPi; } - for ( i = 0; i < 3; i++ ) - Vec_IntFree( vStats[i] ); - Vec_IntFree( vCounts ); - Vec_WrdFree( vSimsPo ); - Vec_WecFree( vCexes ); - Gia_ManStop( pSwp2 ); - //printf( "Compressing inputs: %5d -> %5d\n", Gia_ManCiNum(pSwp), Vec_IntSize(vMap) ); - vSimsPi = Min_ManRemapSims( Gia_ManCiNum(pSwp), vMap, vSimsPo = vSimsPi ); - Vec_WrdFree( vSimsPo ); - Vec_IntFree( vMap ); - return vSimsPi; } Vec_Wrd_t * Min_ManCollect( Gia_Man_t * p, int nConf, int nConf2, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fVerbose, int fVeryVerbose ) { From 41c4d3c09c8a1dd159c477a09482476230b7dbb2 Mon Sep 17 00:00:00 2001 From: Yuri Victorovich Date: Wed, 29 Dec 2021 12:57:23 -0800 Subject: [PATCH 13/74] Add missing class names in FreeBSD-ifdefed code. --- src/sat/glucose/System.cpp | 2 +- src/sat/glucose2/System2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sat/glucose/System.cpp b/src/sat/glucose/System.cpp index 18f2d6564..276eddb88 100644 --- a/src/sat/glucose/System.cpp +++ b/src/sat/glucose/System.cpp @@ -86,7 +86,7 @@ double Gluco::memUsed(void) { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } -double memUsedPeak(void) { return memUsed(); } +double Gluco::memUsedPeak(void) { return memUsed(); } ABC_NAMESPACE_IMPL_END diff --git a/src/sat/glucose2/System2.cpp b/src/sat/glucose2/System2.cpp index 844220a0b..bf16dcd17 100644 --- a/src/sat/glucose2/System2.cpp +++ b/src/sat/glucose2/System2.cpp @@ -86,7 +86,7 @@ double Gluco2::memUsed(void) { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } -double memUsedPeak(void) { return memUsed(); } +double Gluco2::memUsedPeak(void) { return memUsed(); } ABC_NAMESPACE_IMPL_END From 48498af8189ef321ee876065d8947875cf711294 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 29 Dec 2021 13:08:32 -0800 Subject: [PATCH 14/74] Missing class name in the FreeBSD code. --- src/sat/glucose/System.cpp | 2 +- src/sat/glucose2/System2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sat/glucose/System.cpp b/src/sat/glucose/System.cpp index 18f2d6564..276eddb88 100644 --- a/src/sat/glucose/System.cpp +++ b/src/sat/glucose/System.cpp @@ -86,7 +86,7 @@ double Gluco::memUsed(void) { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } -double memUsedPeak(void) { return memUsed(); } +double Gluco::memUsedPeak(void) { return memUsed(); } ABC_NAMESPACE_IMPL_END diff --git a/src/sat/glucose2/System2.cpp b/src/sat/glucose2/System2.cpp index 844220a0b..bf16dcd17 100644 --- a/src/sat/glucose2/System2.cpp +++ b/src/sat/glucose2/System2.cpp @@ -86,7 +86,7 @@ double Gluco2::memUsed(void) { struct rusage ru; getrusage(RUSAGE_SELF, &ru); return (double)ru.ru_maxrss / 1024; } -double memUsedPeak(void) { return memUsed(); } +double Gluco2::memUsedPeak(void) { return memUsed(); } ABC_NAMESPACE_IMPL_END From 79f04c66534c1a517481a2006dcbbb8e27d1688c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jan 2022 11:09:10 -0800 Subject: [PATCH 15/74] Experiments with word-level data structures. --- abclib.dsp | 8 + src/aig/gia/giaDup.c | 14 + src/aig/gia/giaPat2.c | 4 +- src/aig/miniaig/abcOper.h | 4 + src/base/main/mainInt.h | 1 + src/base/wlc/wlcCom.c | 336 ++++--- src/base/wln/module.make | 2 + src/base/wln/wln.h | 4 + src/base/wln/wlnBlast.c | 388 +++++++++ src/base/wln/wlnRead.c | 1733 +++++++++++++++++++++++++++++++++++++ src/base/wln/wlnRtl.c | 48 +- 11 files changed, 2387 insertions(+), 155 deletions(-) create mode 100644 src/base/wln/wlnBlast.c create mode 100644 src/base/wln/wlnRead.c diff --git a/abclib.dsp b/abclib.dsp index 6878f78f6..f5e9f5f8b 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1127,6 +1127,10 @@ SOURCE=.\src\base\wln\wln.h # End Source File # Begin Source File +SOURCE=.\src\base\wln\wlnBlast.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wln\wlnMem.c # End Source File # Begin Source File @@ -1143,6 +1147,10 @@ SOURCE=.\src\base\wln\wlnObj.c # End Source File # Begin Source File +SOURCE=.\src\base\wln\wlnRead.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wln\wlnRetime.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index da4881cdd..55f8901fd 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -1086,6 +1086,20 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo ) Gia_ManSetRegNum( pNew, Gia_ManRegNum(pOne) + Gia_ManRegNum(pTwo) ); return pNew; } +void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ) +{ + Gia_Obj_t * pObj; int i; + assert( Vec_IntSize(vLits) == Gia_ManCiNum(p) ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Vec_IntEntry(vLits, i); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Vec_IntClear( vLits ); + Gia_ManForEachCo( p, pObj, i ) + Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) ); + assert( Vec_IntSize(vLits) == Gia_ManCoNum(p) ); +} /**Function************************************************************* diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index f2cdfe792..fef4cf5a8 100644 --- a/src/aig/gia/giaPat2.c +++ b/src/aig/gia/giaPat2.c @@ -1025,9 +1025,9 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie if ( fVerbose ) printf( "Used simulation for %d and SAT for %d outputs (out of %d).\n", nSimOuts, nSatOuts, nOuts ); if ( fVerbose ) - Abc_PrintTime( 1, "Simulation time ", clkSim ); + Abc_PrintTime( 1, "Simulation time ", clkSim ); if ( fVerbose ) - Abc_PrintTime( 1, "SAT solving time", clkSat ); + Abc_PrintTime( 1, "SAT solving time ", clkSat ); //Vec_WecPrint( vCexes, 0 ); if ( vOuts != vOuts0 ) Vec_IntFreeP( &vOuts ); diff --git a/src/aig/miniaig/abcOper.h b/src/aig/miniaig/abcOper.h index c3d6e1760..cbe2a0f3a 100644 --- a/src/aig/miniaig/abcOper.h +++ b/src/aig/miniaig/abcOper.h @@ -226,6 +226,10 @@ static inline const char * Abc_OperName( int Type ) if ( Type == ABC_OPER_ZEROPAD ) return "zPad"; if ( Type == ABC_OPER_SIGNEXT ) return "sExt"; + if ( Type == ABC_OPER_BIT_MUX ) return "mux"; + if ( Type == ABC_OPER_SEL_NMUX ) return "nmux"; + if ( Type == ABC_OPER_SEL_SEL ) return "pmux"; + if ( Type == ABC_OPER_CONST ) return "const"; if ( Type == ABC_OPER_TABLE ) return "table"; if ( Type == ABC_OPER_LUT ) return "lut"; diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index e860878ec..5325adfe6 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -145,6 +145,7 @@ struct Abc_Frame_t_ void * pAbc85Delay; void * pAbcWlc; Vec_Int_t * pAbcWlcInv; + void * pAbcRtl; void * pAbcBac; void * pAbcCba; void * pAbcPla; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index b1573e731..d8b8247a4 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -32,7 +32,6 @@ ABC_NAMESPACE_IMPL_START static int Abc_CommandReadWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandWriteWlc ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCone ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbs ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -55,12 +54,20 @@ static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSolve ( Abc_Frame_t * pAbc, int argc, char ** argv ); + static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; } + +static inline Rtl_Lib_t * Wlc_AbcGetRtl( Abc_Frame_t * pAbc ) { return (Rtl_Lib_t *)pAbc->pAbcRtl; } +static inline void Wlc_AbcFreeRtl( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcRtl ) Rtl_LibFree(Wlc_AbcGetRtl(pAbc)); } +static inline void Wlc_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib ) { Wlc_AbcFreeRtl(pAbc); pAbc->pAbcRtl = pLib; } + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -80,7 +87,6 @@ void Wlc_Init( Abc_Frame_t * pAbc ) { Cmd_CommandAdd( pAbc, "Word level", "%read", Abc_CommandReadWlc, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%write", Abc_CommandWriteWlc, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%ps", Abc_CommandPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%cone", Abc_CommandCone, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%abs", Abc_CommandAbs, 0 ); @@ -97,6 +103,9 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); @@ -297,130 +306,6 @@ usage: return 1; } -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); - extern Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ); - - FILE * pFile; - char * pFileName = NULL; - char * pTopModule= NULL; - int fCollapse = 0; - int fBlast = 0; - int fInvert = 0; - int fTechMap = 0; - int fSkipStrash = 0; - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Tcaismvh" ) ) != EOF ) - { - switch ( c ) - { - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); - goto usage; - } - pTopModule = argv[globalUtilOptind]; - globalUtilOptind++; - break; - case 'c': - fCollapse ^= 1; - break; - case 'a': - fBlast ^= 1; - break; - case 'i': - fInvert ^= 1; - break; - case 's': - fSkipStrash ^= 1; - break; - case 'm': - fTechMap ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( argc != globalUtilOptind + 1 ) - { - printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); - return 0; - } - // get the file name - pFileName = argv[globalUtilOptind]; - if ( (pFile = fopen( pFileName, "r" )) == NULL ) - { - Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); - if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); - Abc_Print( 1, "\n" ); - return 0; - } - fclose( pFile ); - - // perform reading - if ( fBlast ) - { - Gia_Man_t * pNew = NULL; - if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); - else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); - else - { - printf( "Abc_CommandYosys(): Unknown file extension.\n" ); - return 0; - } - Abc_FrameUpdateGia( pAbc, pNew ); - } - else - { - Wln_Ntk_t * pNtk = NULL; - if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) - pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose ); - else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) - pNtk = Wln_ReadSystemVerilog( pFileName, pTopModule, fVerbose ); - else - { - printf( "Abc_CommandYosys(): Unknown file extension.\n" ); - return 0; - } - //Wlc_AbcUpdateNtk( pAbc, pNtk ); - } - return 0; -usage: - Abc_Print( -2, "usage: %%yosys [-T ] [-caismvh] \n" ); - Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); - Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); - Abc_Print( -2, "\t-c : toggle collapsing the design using Yosys [default = %s]\n", fCollapse? "yes": "no" ); - Abc_Print( -2, "\t-a : toggle bit-blasting the design using Yosys [default = %s]\n", fBlast? "yes": "no" ); - Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); - Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); - Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - /**Function******************************************************************** Synopsis [] @@ -2097,6 +1982,205 @@ usage: return 1; } + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); + extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose ); + + FILE * pFile; + char * pFileName = NULL; + char * pTopModule= NULL; + int fBlast = 0; + int fInvert = 0; + int fTechMap = 1; + int fSkipStrash = 0; + int fCollapse = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Tbismcvh" ) ) != EOF ) + { + switch ( c ) + { + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); + goto usage; + } + pTopModule = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'b': + fBlast ^= 1; + break; + case 'i': + fInvert ^= 1; + break; + case 's': + fSkipStrash ^= 1; + break; + case 'm': + fTechMap ^= 1; + break; + case 'c': + fCollapse ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); + return 0; + } + // get the file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) + { + Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); + if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + + // perform reading + if ( fBlast ) + { + Gia_Man_t * pNew = NULL; + if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); + else + { + printf( "Abc_CommandYosys(): Unknown file extension.\n" ); + return 0; + } + Abc_FrameUpdateGia( pAbc, pNew ); + } + else + { + Rtl_Lib_t * pLib = NULL; + if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) + pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) ) + pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); + else + { + printf( "Abc_CommandYosys(): Unknown file extension.\n" ); + return 0; + } + Wlc_AbcUpdateRtl( pAbc, pLib ); + } + return 0; +usage: + Abc_Print( -2, "usage: %%yosys [-T ] [-bismcvh] \n" ); + Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); + Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); + Abc_Print( -2, "\t-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" ); + Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); + Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Rtl_LibPrintStats( Rtl_Lib_t * p ); + extern void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p ); + extern void Rtl_LibNormRanges( Rtl_Lib_t * pLib ); + extern void Rtl_LibOrderWires( Rtl_Lib_t * pLib ); + extern void Rtl_LibOrderCells( Rtl_Lib_t * pLib ); + extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); + extern void Rtl_LibReorderModules( Rtl_Lib_t * pLib ); + extern void Rtl_LibSolve( Rtl_Lib_t * pLib ); + extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); + + Gia_Man_t * pGia = NULL; + Rtl_Lib_t * pLib = Wlc_AbcGetRtl(pAbc); + int c, fPrepro = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "pvh" ) ) != EOF ) + { + switch ( c ) + { + case 'p': + fPrepro ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + Rtl_LibPrintStats( pLib ); + //Rtl_LibPrint( NULL, pLib ); + Rtl_LibOrderWires( pLib ); + Rtl_LibOrderCells( pLib ); + + Rtl_LibBlast( pLib ); + //Rtl_LibReorderModules( pLib ); + //Rtl_LibPrintStats( pLib ); + + if ( fPrepro ) + Rtl_LibPreprocess( pLib ); + Rtl_LibSolve( pLib ); + + //Rtl_LibPrint( NULL, pLib ); + Wlc_AbcUpdateRtl( pAbc, NULL ); + Gia_ManStopP( &pGia ); + return 0; +usage: + Abc_Print( -2, "usage: %%solve [-pvh]\n" ); + Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "\t-p : toggle preprocessing for verification [default = %s]\n", fPrepro? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wln/module.make b/src/base/wln/module.make index 308f76890..7277f30b3 100644 --- a/src/base/wln/module.make +++ b/src/base/wln/module.make @@ -1,8 +1,10 @@ SRC += src/base/wln/wln.c \ + src/base/wln/wlnBlast.c \ src/base/wln/wlnMem.c \ src/base/wln/wlnNdr.c \ src/base/wln/wlnNtk.c \ src/base/wln/wlnObj.c \ + src/base/wln/wlnRead.c \ src/base/wln/wlnRetime.c \ src/base/wln/wlnRtl.c \ src/base/wln/wlnWlc.c \ diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h index 93a1a92af..c658a2fee 100644 --- a/src/base/wln/wln.h +++ b/src/base/wln/wln.h @@ -251,6 +251,10 @@ extern void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk ); /*=== wlcWriteVer.c ========================================================*/ extern void Wln_WriteVer( Wln_Ntk_t * p, char * pFileName ); +/*=== wlcRead.c ========================================================*/ +typedef struct Rtl_Lib_t_ Rtl_Lib_t; +extern Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec ); +extern void Rtl_LibFree( Rtl_Lib_t * p ); ABC_NAMESPACE_HEADER_END diff --git a/src/base/wln/wlnBlast.c b/src/base/wln/wlnBlast.c new file mode 100644 index 000000000..a3ac73c04 --- /dev/null +++ b/src/base/wln/wlnBlast.c @@ -0,0 +1,388 @@ +/**CFile**************************************************************** + + FileName [wlnBlast.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnBlast.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "base/wlc/wlc.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rtl_VecExtend( Vec_Int_t * p, int nRange, int fSigned ) +{ + Vec_IntFillExtra( p, nRange, fSigned ? Vec_IntEntryLast(p) : 0 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 ) +{ + extern void Wlc_BlastMinus( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vRes ); + extern int Wlc_BlastReduction( Gia_Man_t * pNew, int * pFans, int nFans, int Type ); + extern int Wlc_BlastLess( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits ); + extern int Wlc_BlastLessSigned( Gia_Man_t * pNew, int * pArg0, int * pArg1, int nBits ); + extern void Wlc_BlastShiftRight( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes ); + extern void Wlc_BlastShiftLeft( Gia_Man_t * pNew, int * pNum, int nNum, int * pShift, int nShift, int fSticky, Vec_Int_t * vRes ); + extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0 + extern void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0 + extern int Wlc_NtkCountConstBits( int * pArray, int nSize ); + extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ); + extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ); + extern void Wlc_BlastZeroCondition( Gia_Man_t * pNew, int * pDiv, int nDiv, Vec_Int_t * vRes ); + extern void Wlc_BlastDivider( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes ); + extern void Wlc_BlastDividerSigned( Gia_Man_t * pNew, int * pNum, int nNum, int * pDiv, int nDiv, int fQuo, Vec_Int_t * vRes ); + extern void Wlc_BlastPower( Gia_Man_t * pNew, int * pNum, int nNum, int * pExp, int nExp, Vec_Int_t * vTemp, Vec_Int_t * vRes ); + + int k, iLit, iLit0, iLit1; + if ( nIns == 1 ) + { + Vec_Int_t * vArg = vDatas; + Vec_Int_t * vRes = vDatas+3; + assert( Vec_IntSize(vRes) == 0 ); + if ( Type == ABC_OPER_BIT_INV ) // Y = ~A $not + { + assert( Vec_IntSize(vArg) == nRange ); + Vec_IntForEachEntry( vArg, iLit, k ) + Vec_IntPush( vRes, Abc_LitNot(iLit) ); + return; + } + if ( Type == ABC_OPER_BIT_BUF ) // Y = +A $pos + { + assert( Vec_IntSize(vArg) == nRange ); + Vec_IntForEachEntry( vArg, iLit, k ) + Vec_IntPush( vRes, iLit ); + return; + } + if ( Type == ABC_OPER_ARI_MIN ) // Y = -A $neg + { + assert( Vec_IntSize(vArg) == nRange ); + Wlc_BlastMinus( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), vRes ); + return; + } + if ( Type == ABC_OPER_RED_AND ) // Y = &A $reduce_and + { + assert( nRange == 1 ); + Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_AND ) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + if ( Type == ABC_OPER_RED_OR ) // Y = |A $reduce_or $reduce_bool + { + assert( nRange == 1 ); + Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + if ( Type == ABC_OPER_RED_XOR ) // Y = ^A $reduce_xor + { + assert( nRange == 1 ); + Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_XOR ) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + if ( Type == ABC_OPER_RED_NXOR ) // Y = ~^A $reduce_xnor + { + assert( nRange == 1 ); + Vec_IntPush( vRes, Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_NXOR ) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + if ( Type == ABC_OPER_LOGIC_NOT ) // Y = !A $logic_not + { + int iLit = Wlc_BlastReduction( pNew, Vec_IntArray(vArg), Vec_IntSize(vArg), WLC_OBJ_REDUCT_OR ); + assert( nRange == 1 ); + Vec_IntFill( vRes, 1, Abc_LitNot(iLit) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + assert( 0 ); + return; + } + + if ( nIns == 2 ) + { + Vec_Int_t * vArg0 = vDatas; + Vec_Int_t * vArg1 = vDatas+1; + Vec_Int_t * vRes = vDatas+3; + int nRangeMax = Abc_MaxInt( nRange, Abc_MaxInt(Vec_IntSize(vArg0), Vec_IntSize(vArg1)) ); + int nSizeArg0 = Vec_IntSize(vArg0); + int nSizeArg1 = Vec_IntSize(vArg1); + Rtl_VecExtend( vArg0, nRangeMax, fSign0 ); + Rtl_VecExtend( vArg1, nRangeMax, fSign1 ); + assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) ); + assert( Vec_IntSize(vRes) == 0 ); + if ( Type == ABC_OPER_LOGIC_AND ) // Y = A && B $logic_and + { + int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR ); + int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR ); + assert( 1 == nRange ); + Vec_IntFill( vRes, 1, Gia_ManHashAnd(pNew, iLit0, iLit1) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + if ( Type == ABC_OPER_LOGIC_OR ) // Y = A || B $logic_or + { + int iLit0 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg0), Vec_IntSize(vArg0), WLC_OBJ_REDUCT_OR ); + int iLit1 = Wlc_BlastReduction( pNew, Vec_IntArray(vArg1), Vec_IntSize(vArg1), WLC_OBJ_REDUCT_OR ); + assert( 1 == nRange ); + Vec_IntFill( vRes, 1, Gia_ManHashOr(pNew, iLit0, iLit1) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + + if ( Type == ABC_OPER_BIT_AND ) // Y = A & B $and + { + Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) + Vec_IntPush( vRes, Gia_ManHashAnd(pNew, iLit0, iLit1) ); + Vec_IntShrink( vRes, nRange ); + return; + } + if ( Type == ABC_OPER_BIT_OR ) // Y = A | B $or + { + Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) + Vec_IntPush( vRes, Gia_ManHashOr(pNew, iLit0, iLit1) ); + Vec_IntShrink( vRes, nRange ); + return; + } + if ( Type == ABC_OPER_BIT_XOR ) // Y = A ^ B $xor + { + Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) + Vec_IntPush( vRes, Gia_ManHashXor(pNew, iLit0, iLit1) ); + Vec_IntShrink( vRes, nRange ); + return; + } + if ( Type == ABC_OPER_BIT_NXOR ) // Y = A ~^ B $xnor + { + assert( Vec_IntSize(vArg0) == nRange ); + Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) + Vec_IntPush( vRes, Abc_LitNot(Gia_ManHashXor(pNew, iLit0, iLit1)) ); + Vec_IntShrink( vRes, nRange ); + return; + } +/* + if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt + if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le + if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge + if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt + if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq + if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne +*/ + if ( Type == ABC_OPER_COMP_EQU || Type == ABC_OPER_COMP_NOTEQU ) + { + iLit = 0; + assert( nRange == 1 ); + Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) + iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, iLit0, iLit1) ); + Vec_IntFill( vRes, 1, Abc_LitNotCond(iLit, Type == ABC_OPER_COMP_EQU) ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } + if ( Type == ABC_OPER_COMP_LESS || Type == ABC_OPER_COMP_LESSEQU || + Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_MOREEQU ) + { + int fSigned = fSign0 && fSign1; + int fSwap = (Type == ABC_OPER_COMP_MORE || Type == ABC_OPER_COMP_LESSEQU); + int fCompl = (Type == ABC_OPER_COMP_MOREEQU || Type == ABC_OPER_COMP_LESSEQU); + assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) ); + assert( nRange == 1 ); + if ( fSwap ) + ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 ) + if ( fSigned ) + iLit = Wlc_BlastLessSigned( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) ); + else + iLit = Wlc_BlastLess( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0) ); + iLit = Abc_LitNotCond( iLit, fCompl ); + Vec_IntFill( vRes, 1, iLit ); + for ( k = 1; k < nRange; k++ ) + Vec_IntPush( vRes, 0 ); + return; + } +/* + if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl + if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr + if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl + if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr +*/ + if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA || + Type == ABC_OPER_SHIFT_L || Type == ABC_OPER_SHIFT_LA ) + { + Vec_IntShrink( vArg1, nSizeArg1 ); + if ( Type == ABC_OPER_SHIFT_R || Type == ABC_OPER_SHIFT_RA ) + Wlc_BlastShiftRight( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, fSign0 && Type == ABC_OPER_SHIFT_RA, vRes ); + else + Wlc_BlastShiftLeft( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nSizeArg1, 0, vRes ); + Vec_IntShrink( vRes, nRange ); + return; + } +/* + if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add + if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub + if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul + if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div + if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod + if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow +*/ + if ( Type == ABC_OPER_ARI_ADD || Type == ABC_OPER_ARI_SUB ) + { + //Vec_IntPrint( vArg0 ); + //Vec_IntPrint( vArg1 ); + Vec_IntAppend( vRes, vArg0 ); + if ( Type == ABC_OPER_ARI_ADD ) + Wlc_BlastAdder( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 0 ); // result is in pFan0 (vRes) + else + Wlc_BlastSubtract( pNew, Vec_IntArray(vRes), Vec_IntArray(vArg1), nRangeMax, 1 ); // result is in pFan0 (vRes) + Vec_IntShrink( vRes, nRange ); + return; + } + if ( Type == ABC_OPER_ARI_MUL ) + { + int fBooth = 1; + int fCla = 0; + int fSigned = fSign0 && fSign1; + Vec_IntShrink( vArg0, nSizeArg0 ); + Vec_IntShrink( vArg1, nSizeArg1 ); + if ( Wlc_NtkCountConstBits(Vec_IntArray(vArg0), Vec_IntSize(vArg0)) < Wlc_NtkCountConstBits(Vec_IntArray(vArg1), Vec_IntSize(vArg1)) ) + ABC_SWAP( Vec_Int_t, *vArg0, *vArg1 ) + if ( fBooth ) + Wlc_BlastBooth( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL ); + else + Wlc_BlastMultiplier3( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), Vec_IntSize(vArg0), Vec_IntSize(vArg1), vRes, fSigned, fCla, NULL ); + if ( nRange > Vec_IntSize(vRes) ) + Vec_IntFillExtra( vRes, nRange, fSigned ? Vec_IntEntryLast(vRes) : 0 ); + else + Vec_IntShrink( vRes, nRange ); + assert( Vec_IntSize(vRes) == nRange ); + return; + } + if ( Type == ABC_OPER_ARI_DIV || Type == ABC_OPER_ARI_MOD ) + { + int fDivBy0 = 1; // correct with 1 + int fSigned = fSign0 && fSign1; + if ( fSigned ) + Wlc_BlastDividerSigned( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes ); + else + Wlc_BlastDivider( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), nRangeMax, Type == ABC_OPER_ARI_DIV, vRes ); + Vec_IntShrink( vRes, nRange ); + if ( !fDivBy0 ) + Wlc_BlastZeroCondition( pNew, Vec_IntArray(vArg1), nRange, vRes ); + return; + } + if ( Type == ABC_OPER_ARI_POW ) + { + Vec_Int_t * vTemp = vDatas+4; + Vec_IntGrow( vTemp, nRangeMax ); + Vec_IntGrow( vRes, nRangeMax ); + Vec_IntShrink( vArg1, nSizeArg1 ); + Wlc_BlastPower( pNew, Vec_IntArray(vArg0), nRangeMax, Vec_IntArray(vArg1), Vec_IntSize(vArg1), vTemp, vRes ); + Vec_IntShrink( vRes, nRange ); + return; + } + } + + if ( nIns == 3 ) + { + if ( Type == ABC_OPER_SEL_NMUX ) // $mux + { + Vec_Int_t * vArg0 = vDatas; + Vec_Int_t * vArg1 = vDatas+1; + Vec_Int_t * vArgS = vDatas+2; + Vec_Int_t * vRes = vDatas+3; + int iCtrl = Vec_IntEntry(vArgS, 0); + //Vec_IntPrint( vArg0 ); + //Vec_IntPrint( vArg1 ); + //Vec_IntPrint( vArgS ); + assert( Vec_IntSize(vArg0) == Vec_IntSize(vArg1) ); + assert( Vec_IntSize(vArg0) == nRange ); + assert( Vec_IntSize(vArgS) == 1 ); + assert( Vec_IntSize(vRes) == 0 ); + Vec_IntForEachEntryTwo( vArg0, vArg1, iLit0, iLit1, k ) + Vec_IntPush( vRes, Gia_ManHashMux(pNew, iCtrl, iLit1, iLit0) ); + return; + } + if ( Type == ABC_OPER_SEL_SEL ) // $pmux + { + int i, k, iLit; + Vec_Int_t * vArgA = vDatas; + Vec_Int_t * vArgB = vDatas+1; + Vec_Int_t * vArgS = vDatas+2; + Vec_Int_t * vRes = vDatas+3; + Vec_Int_t * vTemp = vDatas+4; + assert( Vec_IntSize(vArgA) == nRange ); // widthA = widthY + assert( Vec_IntSize(vArgB) == Vec_IntSize(vArgA)*Vec_IntSize(vArgS) ); // widthB == widthA*widthS + assert( Vec_IntSize(vRes) == 0 ); + for ( i = 0; i < nRange; i++ ) + { + int iCond = 1; + Vec_IntClear( vTemp ); + Vec_IntForEachEntry( vArgS, iLit, k ) // iLit = S[i] + { + //Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*(Vec_IntSize(vArgS)-1-k)+i)) ) ); // B[widthA*k+i] + Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iLit, Vec_IntEntry(vArgB, nRange*k+i)) ) ); // B[widthA*k+i] + iCond = Gia_ManHashAnd( pNew, iCond, Abc_LitNot(iLit) ); + } + Vec_IntPush( vTemp, Abc_LitNot( Gia_ManHashAnd(pNew, iCond, Vec_IntEntry(vArgA, i)) ) ); + Vec_IntPush( vRes, Abc_LitNot( Gia_ManHashAndMulti(pNew, vTemp) ) ); + } + return; + } + } +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c new file mode 100644 index 000000000..492005fdb --- /dev/null +++ b/src/base/wln/wlnRead.c @@ -0,0 +1,1733 @@ +/**CFile**************************************************************** + + FileName [wln.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "proof/cec/cec.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_LINE 10000 + +#define MAX_MAP 32 +#define CELL_NUM 8 +#define WIRE_NUM 5 +#define TEMP_NUM 5 + +//typedef struct Rtl_Lib_t_ Rtl_Lib_t; +struct Rtl_Lib_t_ +{ + char * pSpec; // input file name + Vec_Ptr_t * vNtks; // modules + Abc_Nam_t * pManName; // object names + Vec_Int_t vConsts; // constants + Vec_Int_t vSlices; // selections + Vec_Int_t vConcats; // concatenations + FILE * pFile; // temp file + Vec_Int_t * vTokens; // temp tokens + int pMap[MAX_MAP]; // temp map + Vec_Int_t * vMap; // mapping NameId into wires + Vec_Int_t vAttrTemp; // temp + Vec_Int_t vTemp[TEMP_NUM]; // temp +}; + +typedef struct Rtl_Ntk_t_ Rtl_Ntk_t; +struct Rtl_Ntk_t_ +{ + int NameId; // model name + int nInputs; // word-level inputs + int nOutputs; // word-level outputs + Vec_Int_t vWires; // wires (name{upto,signed,in,out}+width+offset+number) + Vec_Int_t vCells; // instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[6]mark+(attr+params+conns)) + Vec_Int_t vConns; // connection pairs + Vec_Int_t vStore; // storage for cells + Vec_Int_t vAttrs; // attributes + Rtl_Lib_t * pLib; // parent + Vec_Int_t vOrder; // topological order + Vec_Int_t vLits; // bit-level view + Vec_Int_t vBitTemp; // storage for bits + Gia_Man_t * pGia; // derived by bit-blasting + int Slice0; // first slice + int Slice1; // last slice + int iCopy; // place in array +}; + +static inline int Rtl_LibNtkNum( Rtl_Lib_t * pLib ) { return Vec_PtrSize(pLib->vNtks); } +static inline Rtl_Ntk_t * Rtl_LibNtk( Rtl_Lib_t * pLib, int i ) { return (Rtl_Ntk_t *)Vec_PtrEntry(pLib->vNtks, i); } +static inline Rtl_Ntk_t * Rtl_LibTop( Rtl_Lib_t * pLib ) { return Rtl_LibNtk( pLib, Rtl_LibNtkNum(pLib)-1 ); } + +static inline Rtl_Ntk_t * Rtl_NtkModule( Rtl_Ntk_t * p, int i ) { return Rtl_LibNtk( p->pLib, i ); } + +static inline int Rtl_NtkStrId( Rtl_Ntk_t * p, char * s ) { return Abc_NamStrFind(p->pLib->pManName, s); } +static inline char * Rtl_NtkStr( Rtl_Ntk_t * p, int h ) { return Abc_NamStr(p->pLib->pManName, h); } +static inline char * Rtl_NtkName( Rtl_Ntk_t * p ) { return Rtl_NtkStr(p, p->NameId); } + +static inline FILE * Rtl_NtkFile( Rtl_Ntk_t * p ) { return p->pLib->pFile; } +static inline int Rtl_NtkTokId( Rtl_Ntk_t * p, int i ) { return i < Vec_IntSize(p->pLib->vTokens) ? Vec_IntEntry(p->pLib->vTokens, i) : -1; } +static inline char * Rtl_NtkTokStr( Rtl_Ntk_t * p, int i ) { return i < Vec_IntSize(p->pLib->vTokens) ? Rtl_NtkStr(p, Vec_IntEntry(p->pLib->vTokens, i)) : NULL; } +static inline int Rtl_NtkTokCheck( Rtl_Ntk_t * p, int i, int Tok ) { return i == p->pLib->pMap[Tok]; } +static inline int Rtl_NtkPosCheck( Rtl_Ntk_t * p, int i, int Tok ) { return Vec_IntEntry(p->pLib->vTokens, i) == p->pLib->pMap[Tok]; } + +static inline int Rtl_NtkInputNum( Rtl_Ntk_t * p ) { return p->nInputs; } +static inline int Rtl_NtkOutputNum( Rtl_Ntk_t * p ) { return p->nOutputs; } +static inline int Rtl_NtkAttrNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vAttrs)/2; } +static inline int Rtl_NtkWireNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vWires)/WIRE_NUM; } +static inline int Rtl_NtkCellNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vCells); } +static inline int Rtl_NtkConNum( Rtl_Ntk_t * p ) { return Vec_IntSize(&p->vConns)/2; } +static inline int Rtl_NtkObjNum( Rtl_Ntk_t * p ) { return p->nInputs + p->nOutputs + Rtl_NtkCellNum(p) + Rtl_NtkConNum(p); } + +static inline int * Rtl_NtkWire( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vWires, WIRE_NUM*i); } +static inline int * Rtl_NtkCell( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vStore, Vec_IntEntry(&p->vCells, i)); } +static inline int * Rtl_NtkCon( Rtl_Ntk_t * p, int i ) { return Vec_IntEntryP(&p->vConns, 2*i); } + +static inline int Rtl_WireName( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i) >> 4; } +static inline char * Rtl_WireNameStr( Rtl_Ntk_t * p, int i ) { return Rtl_NtkStr(p, Rtl_WireName(p, i)); } +static inline int Rtl_WireFirst( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i); } +static inline int Rtl_WireWidth( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+1); } +static inline int Rtl_WireOffset( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+2); } +static inline int Rtl_WireNumber( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+3); } +static inline int Rtl_WireBitStart( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(&p->vWires, WIRE_NUM*i+4); } +static inline int Rtl_WireMapNameToId( Rtl_Ntk_t * p, int i ) { return Vec_IntEntry(p->pLib->vMap, i); } + +static inline int Rtl_CellType( int * pCell ) { return pCell[0]; } +static inline int Rtl_CellName( int * pCell ) { return pCell[1]; } +static inline int Rtl_CellModule( int * pCell ) { return pCell[2]; } +static inline int Rtl_CellInputNum( int * pCell ) { return pCell[3]; } +static inline int Rtl_CellOutputNum( int * pCell ) { return pCell[6]-pCell[3]; } +static inline int Rtl_CellAttrNum( int * pCell ) { return pCell[4]; } +static inline int Rtl_CellParamNum( int * pCell ) { return pCell[5]; } +static inline int Rtl_CellConNum( int * pCell ) { return pCell[6]; } +static inline int Rtl_CellMark( int * pCell ) { return pCell[7]; } +static inline Rtl_Ntk_t * Rtl_CellNtk( Rtl_Ntk_t * p, int * pCell ) { return Rtl_CellModule(pCell) >= ABC_INFINITY ? Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY) : NULL; } + +static inline char * Rtl_CellTypeStr( Rtl_Ntk_t * p, int * pCell ) { return Rtl_NtkStr(p, Rtl_CellType(pCell)); } +static inline char * Rtl_CellNameStr( Rtl_Ntk_t * p, int * pCell ) { return Rtl_NtkStr(p, Rtl_CellName(pCell)); } + +static inline int Rtl_SigIsNone( int s ) { return (s & 0x3) == 0; } +static inline int Rtl_SigIsConst( int s ) { return (s & 0x3) == 1; } +static inline int Rtl_SigIsSlice( int s ) { return (s & 0x3) == 2; } +static inline int Rtl_SigIsConcat( int s ) { return (s & 0x3) == 3; } + +#define Rtl_NtkForEachAttr( p, Par, Val, i ) \ + for ( i = 0; i < Rtl_NtkAttrNum(p) && (Par = Vec_IntEntry(&p->vAttrs, 2*i)) && (Val = Vec_IntEntry(&p->vAttrs, 2*i+1)); i++ ) +#define Rtl_NtkForEachWire( p, pWire, i ) \ + for ( i = 0; i < Rtl_NtkWireNum(p) && (pWire = Vec_IntEntryP(&p->vWires, WIRE_NUM*i)); i++ ) +#define Rtl_NtkForEachCell( p, pCell, i ) \ + for ( i = 0; i < Rtl_NtkCellNum(p) && (pCell = Rtl_NtkCell(p, i)); i++ ) +#define Rtl_NtkForEachCon( p, pCon, i ) \ + for ( i = 0; i < Rtl_NtkConNum(p) && (pCon = Vec_IntEntryP(&p->vConns, 2*i)); i++ ) + +#define Rtl_CellForEachAttr( p, pCell, Par, Val, i ) \ + for ( i = 0; i < pCell[4] && (Par = pCell[CELL_NUM+2*i]) && (Val = pCell[CELL_NUM+2*i+1]); i++ ) +#define Rtl_CellForEachParam( p, pCell, Par, Val, i ) \ + for ( i = 0; i < pCell[5] && (Par = pCell[CELL_NUM+2*(pCell[4]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+i)+1]); i++ ) +#define Rtl_CellForEachConnect( p, pCell, Par, Val, i ) \ + for ( i = 0; i < pCell[6] && (Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)]) && (Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+i)+1]); i++ ) + +#define Rtl_CellForEachInput( p, pCell, Par, Val, i ) \ + Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i >= Rtl_CellInputNum(pCell) ) continue; else +#define Rtl_CellForEachOutput( p, pCell, Par, Val, i ) \ + Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i < Rtl_CellInputNum(pCell) ) continue; else + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Rtl_Ntk_t * Rtl_NtkAlloc( Rtl_Lib_t * pLib ) +{ + Rtl_Ntk_t * p = ABC_CALLOC( Rtl_Ntk_t, 1 ); + Vec_IntGrow( &p->vWires, 4 ); + Vec_IntGrow( &p->vCells, 4 ); + Vec_IntGrow( &p->vConns, 4 ); + Vec_IntGrow( &p->vStore, 8 ); + Vec_IntGrow( &p->vAttrs, 8 ); + Vec_PtrPush( pLib->vNtks, (void *)p ); + p->pLib = pLib; + return p; +} +void Rtl_NtkFree( Rtl_Ntk_t * p ) +{ + Gia_ManStopP( &p->pGia ); + ABC_FREE( p->vWires.pArray ); + ABC_FREE( p->vCells.pArray ); + ABC_FREE( p->vConns.pArray ); + ABC_FREE( p->vStore.pArray ); + ABC_FREE( p->vAttrs.pArray ); + ABC_FREE( p->vOrder.pArray ); + ABC_FREE( p->vLits.pArray ); + ABC_FREE( p->vBitTemp.pArray ); + ABC_FREE( p ); +} +void Rtl_NtkCountPio( Rtl_Ntk_t * p, int Counts[4] ) +{ + int i, * pWire; + Rtl_NtkForEachWire( p, pWire, i ) + { + if ( pWire[0] & 1 ) // PI + Counts[0]++, Counts[1] += pWire[1]; + if ( pWire[0] & 2 ) // PO + Counts[2]++, Counts[3] += pWire[1]; + } + assert( p->nInputs == Counts[0] ); + assert( p->nOutputs == Counts[2] ); +} +void Rtl_NtkPrintOpers( Rtl_Ntk_t * p ) +{ + int i, * pCell, nBlack = 0, nUser = 0, Counts[ABC_OPER_LAST] = {0}; + if ( Rtl_NtkCellNum(p) == 0 ) + return; + Rtl_NtkForEachCell( p, pCell, i ) + if ( Rtl_CellModule(pCell) < ABC_OPER_LAST ) + Counts[Rtl_CellModule(pCell)]++; + else if ( Rtl_CellModule(pCell) == ABC_OPER_LAST-1 ) + nBlack++; + else + nUser++; + printf( "There are %d instances in this network:\n", Rtl_NtkCellNum(p) ); + if ( nBlack ) + printf( " %s (%d)", "blackbox", nBlack ); + if ( nUser ) + printf( " %s (%d)", "user", nUser ); + for ( i = 0; i < ABC_OPER_LAST; i++ ) + if ( Counts[i] ) + printf( " %s (%d)", Abc_OperName(i), Counts[i] ); + printf( "\n" ); +} +void Rtl_NtkPrintStats( Rtl_Ntk_t * p, int nNameSymbs ) +{ + int Counts[4] = {0}; Rtl_NtkCountPio( p, Counts ); + printf( "%*s : ", nNameSymbs, Rtl_NtkName(p) ); + printf( "PI = %3d (%3d) ", Counts[0], Counts[1] ); + printf( "PO = %3d (%3d) ", Counts[2], Counts[3] ); + printf( "Wire = %6d ", Rtl_NtkWireNum(p) ); + printf( "Cell = %6d ", Rtl_NtkCellNum(p) ); + printf( "Con = %6d", Rtl_NtkConNum(p) ); + printf( "\n" ); + //Rtl_NtkPrintOpers( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Rtl_Lib_t * Rtl_LibAlloc() +{ + Rtl_Lib_t * p = ABC_CALLOC( Rtl_Lib_t, 1 ); + p->vNtks = Vec_PtrAlloc( 100 ); + Vec_IntGrow( &p->vConsts, 1000 ); + Vec_IntGrow( &p->vSlices, 1000 ); + Vec_IntGrow( &p->vConcats, 1000 ); + return p; +} +void Rtl_LibFree( Rtl_Lib_t * p ) +{ + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + Rtl_NtkFree( pNtk ); + ABC_FREE( p->vConsts.pArray ); + ABC_FREE( p->vSlices.pArray ); + ABC_FREE( p->vConcats.pArray ); + ABC_FREE( p->vAttrTemp.pArray ); + for ( i = 0; i < TEMP_NUM; i++ ) + ABC_FREE( p->vTemp[i].pArray ); + Vec_IntFreeP( &p->vMap ); + Vec_IntFreeP( &p->vTokens ); + Abc_NamStop( p->pManName ); + Vec_PtrFree( p->vNtks ); + ABC_FREE( p->pSpec ); + ABC_FREE( p ); +} +int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId ) +{ + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + if ( pNtk->NameId == NameId ) + return i; + return -1; +} +void Rtl_LibPrintStats( Rtl_Lib_t * p ) +{ + Rtl_Ntk_t * pNtk; int i, nSymbs = 0; + printf( "Modules found in \"%s\":\n", p->pSpec ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + nSymbs = Abc_MaxInt( nSymbs, strlen(Rtl_NtkName(pNtk)) ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + Rtl_NtkPrintStats( pNtk, nSymbs + 2 ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +typedef enum { + RTL_NONE = 0, // 0: unused + RTL_MODULE, // 1: "module" + RTL_END, // 2: "end" + RTL_INPUT, // 3: "input" + RTL_OUTPUT, // 4: "output" + RTL_INOUT, // 5: "inout" + RTL_UPTO, // 6: "upto" + RTL_SIGNED, // 7: "signed" + RTL_OFFSET, // 8: "offset" + RTL_PARAMETER, // 9: "parameter" + RTL_WIRE, // 10: "wire" + RTL_CONNECT, // 11: "connect" + RTL_CELL, // 12: "cell" + RTL_WIDTH, // 13: "width" + RTL_ATTRIBUTE, // 14: "attribute" + RTL_UNUSED // 15: unused +} Rtl_Type_t; + +static inline char * Rtl_Num2Name( int i ) +{ + if ( i == 1 ) return "module"; + if ( i == 2 ) return "end"; + if ( i == 3 ) return "input"; + if ( i == 4 ) return "output"; + if ( i == 5 ) return "inout"; + if ( i == 6 ) return "upto"; + if ( i == 7 ) return "signed"; + if ( i == 8 ) return "offset"; + if ( i == 9 ) return "parameter"; + if ( i == 10 ) return "wire"; + if ( i == 11 ) return "connect"; + if ( i == 12 ) return "cell"; + if ( i == 13 ) return "width"; + if ( i == 14 ) return "attribute"; + return NULL; +} + +static inline void Rtl_LibDeriveMap( Rtl_Lib_t * p ) +{ + int i; + p->pMap[0] = -1; + for ( i = 1; i < RTL_UNUSED; i++ ) + p->pMap[i] = Abc_NamStrFind( p->pManName, Rtl_Num2Name(i) ); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rtl_LibReadType( char * pType ) +{ + if ( !strcmp(pType, "$not") ) return ABC_OPER_BIT_INV; // Y = ~A $not + if ( !strcmp(pType, "$pos") ) return ABC_OPER_BIT_BUF; // Y = +A $pos + if ( !strcmp(pType, "$neg") ) return ABC_OPER_ARI_MIN; // Y = -A $neg + if ( !strcmp(pType, "$reduce_and") ) return ABC_OPER_RED_AND; // Y = &A $reduce_and + if ( !strcmp(pType, "$reduce_or") ) return ABC_OPER_RED_OR; // Y = |A $reduce_or + if ( !strcmp(pType, "$reduce_xor") ) return ABC_OPER_RED_XOR; // Y = ^A $reduce_xor + if ( !strcmp(pType, "$reduce_xnor") ) return ABC_OPER_RED_NXOR; // Y = ~^A $reduce_xnor + if ( !strcmp(pType, "$reduce_bool") ) return ABC_OPER_RED_OR; // Y = |A $reduce_bool + if ( !strcmp(pType, "$logic_not") ) return ABC_OPER_LOGIC_NOT; // Y = !A $logic_not + + if ( !strcmp(pType, "$and") ) return ABC_OPER_BIT_AND; // Y = A & B $and + if ( !strcmp(pType, "$or") ) return ABC_OPER_BIT_OR; // Y = A | B $or + if ( !strcmp(pType, "$xor") ) return ABC_OPER_BIT_XOR; // Y = A ^ B $xor + if ( !strcmp(pType, "$xnor") ) return ABC_OPER_BIT_NXOR; // Y = A ~^ B $xnor + + if ( !strcmp(pType, "$shl") ) return ABC_OPER_SHIFT_L; // Y = A << B $shl + if ( !strcmp(pType, "$shr") ) return ABC_OPER_SHIFT_R; // Y = A >> B $shr + if ( !strcmp(pType, "$sshl") ) return ABC_OPER_SHIFT_LA; // Y = A <<< B $sshl + if ( !strcmp(pType, "$sshr") ) return ABC_OPER_SHIFT_RA; // Y = A >>> B $sshr + + if ( !strcmp(pType, "$shiftx") ) return ABC_OPER_SHIFT_R; // Y = A << B $shl <== temporary + + if ( !strcmp(pType, "$logic_and") ) return ABC_OPER_LOGIC_AND; // Y = A && B $logic_and + if ( !strcmp(pType, "$logic_or") ) return ABC_OPER_LOGIC_OR; // Y = A || B $logic_or + + if ( !strcmp(pType, "$lt") ) return ABC_OPER_COMP_LESS; // Y = A < B $lt + if ( !strcmp(pType, "$le") ) return ABC_OPER_COMP_LESSEQU; // Y = A <= B $le + if ( !strcmp(pType, "$ge") ) return ABC_OPER_COMP_MOREEQU; // Y = A >= B $ge + if ( !strcmp(pType, "$gt") ) return ABC_OPER_COMP_MORE; // Y = A > B $gt + if ( !strcmp(pType, "$eq") ) return ABC_OPER_COMP_EQU; // Y = A == B $eq + if ( !strcmp(pType, "$ne") ) return ABC_OPER_COMP_NOTEQU; // Y = A != B $ne + if ( !strcmp(pType, "$eqx") ) return ABC_OPER_COMP_EQU; // Y = A === B $eqx + if ( !strcmp(pType, "$nex") ) return ABC_OPER_COMP_NOTEQU; // Y = A !== B $nex + + if ( !strcmp(pType, "$add") ) return ABC_OPER_ARI_ADD; // Y = A + B $add + if ( !strcmp(pType, "$sub") ) return ABC_OPER_ARI_SUB; // Y = A - B $sub + if ( !strcmp(pType, "$mul") ) return ABC_OPER_ARI_MUL; // Y = A * B $mul + if ( !strcmp(pType, "$div") ) return ABC_OPER_ARI_DIV; // Y = A / B $div + if ( !strcmp(pType, "$mod") ) return ABC_OPER_ARI_MOD; // Y = A % B $mod + if ( !strcmp(pType, "$pow") ) return ABC_OPER_ARI_POW; // Y = A ** B $pow + + if ( !strcmp(pType, "$modfoor") ) return ABC_OPER_NONE; // [N/A] $modfoor + if ( !strcmp(pType, "$divfloor") ) return ABC_OPER_NONE; // [N/A] $divfloor + + if ( !strcmp(pType, "$mux") ) return ABC_OPER_SEL_NMUX; // $mux + if ( !strcmp(pType, "$pmux") ) return ABC_OPER_SEL_SEL; // $pmux + + if ( !strcmp(pType, "$dff") ) return ABC_OPER_DFF; + if ( !strcmp(pType, "$adff") ) return ABC_OPER_DFF; + if ( !strcmp(pType, "$sdff") ) return ABC_OPER_DFF; + assert( 0 ); + return -1; +} +int Rtl_NtkReadType( Rtl_Ntk_t * p, int Type ) +{ + extern int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId ); + char * pType = Rtl_NtkStr( p, Type ); + if ( pType[0] == '$' && strncmp(pType,"$paramod",strlen("$paramod")) ) + return Rtl_LibReadType( pType ); + return ABC_INFINITY + Rtl_LibFindModule( p->pLib, Type ); +} + +/**Function************************************************************* + + Synopsis [There is no need to normalize ranges in Yosys.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rtl_NtkRangeWires( Rtl_Ntk_t * p ) +{ + int i, * pWire, nBits = 0; + Rtl_NtkForEachWire( p, pWire, i ) + { + //printf( "%s -> %d\n", Rtl_WireNameStr(p, i), nBits ); + pWire[4] = nBits, nBits += Rtl_WireWidth(p, i); + } + return nBits; +} +void Rtl_NtkMapWires( Rtl_Ntk_t * p, int fUnmap ) +{ + int i, Value; + assert( Vec_IntSize(p->pLib->vMap) == Abc_NamObjNumMax(p->pLib->pManName) ); + for ( i = 0; i < Rtl_NtkWireNum(p); i++ ) + { + int NameId = Rtl_WireName( p, i ); + assert( Vec_IntEntry(p->pLib->vMap, NameId) == (fUnmap ? i : -1) ); + Vec_IntWriteEntry( p->pLib->vMap, NameId, fUnmap ? -1 : i ); + } + if ( fUnmap ) + Vec_IntForEachEntry( p->pLib->vMap, Value, i ) + assert( Value == -1 ); +} +void Rtl_NtkNormRanges( Rtl_Ntk_t * p ) +{ + int i, * pWire; + Rtl_NtkMapWires( p, 0 ); + for ( i = p->Slice0; i < p->Slice1; i += 3 ) + { + int NameId = Vec_IntEntry( &p->pLib->vSlices, i ); + int Left = Vec_IntEntry( &p->pLib->vSlices, i+1 ); + int Right = Vec_IntEntry( &p->pLib->vSlices, i+2 ); + int Wire = Rtl_WireMapNameToId( p, NameId ); + int Offset = Rtl_WireOffset( p, Wire ); + int First = Rtl_WireFirst( p, Wire ); + assert( First >> 4 == NameId ); + if ( Offset ); + { + Left -= Offset; + Right -= Offset; + } + if ( First & 8 ) // upto + { + Vec_IntWriteEntry( &p->pLib->vSlices, i+1, Right ); + Vec_IntWriteEntry( &p->pLib->vSlices, i+2, Left ); + } + } + Rtl_NtkForEachWire( p, pWire, i ) + { + Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+0, Rtl_WireFirst(p, i) & ~0x8 ); // upto + Vec_IntWriteEntry( &p->vWires, WIRE_NUM*i+2, 0 ); // offset + } + Rtl_NtkMapWires( p, 1 ); +} +void Rtl_LibNormRanges( Rtl_Lib_t * pLib ) +{ + Rtl_Ntk_t * p; int i; + if ( pLib->vMap == NULL ) + pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + Rtl_NtkNormRanges( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Rlt_NtkFindIOPerm( Rtl_Ntk_t * p ) +{ + Vec_Int_t * vCost = Vec_IntAlloc( 100 ); + int i, * pWire, * pPerm = NULL, Count = 0; + Rtl_NtkForEachWire( p, pWire, i ) + { + int First = Rtl_WireFirst( p, i ); + int Number = Rtl_WireNumber( p, i ); + int fIsPi = (int)((First & 1) > 0); + int fIsPo = (int)((First & 2) > 0); + assert( (fIsPi || fIsPo) == (Number > 0) ); + if ( fIsPi || fIsPo ) + Vec_IntPush( vCost, fIsPo*ABC_INFINITY + Number ); + else + Vec_IntPush( vCost, 2*ABC_INFINITY + Count++ ); + } + pPerm = Abc_MergeSortCost( Vec_IntArray(vCost), Vec_IntSize(vCost) ); + Vec_IntFree( vCost ); + return pPerm; +} +void Rtl_NtkOrderWires( Rtl_Ntk_t * p ) +{ + Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(&p->vWires) ); + int i, k, * pWire, * pPerm = Rlt_NtkFindIOPerm( p ); + Rtl_NtkForEachWire( p, pWire, i ) + { + pWire = Vec_IntEntryP( &p->vWires, WIRE_NUM*pPerm[i] ); + for ( k = 0; k < WIRE_NUM; k++ ) + Vec_IntPush( vTemp, pWire[k] ); + } + ABC_FREE( pPerm ); + assert( Vec_IntSize(&p->vWires) == Vec_IntSize(vTemp) ); + ABC_SWAP( Vec_Int_t, p->vWires, *vTemp ); + Vec_IntFree( vTemp ); +} +void Rtl_LibUpdateInstances( Rtl_Ntk_t * p ) +{ + Vec_Int_t * vMap = p->pLib->vMap; + Vec_Int_t * vTemp = &p->pLib->vTemp[2]; + int i, k, Par, Val, * pCell, Value; + Rtl_NtkForEachCell( p, pCell, i ) + if ( Rtl_CellModule(pCell) >= ABC_INFINITY ) + { + Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); + assert( pCell[6] == pModel->nInputs+pModel->nOutputs ); + Rtl_CellForEachConnect( p, pCell, Par, Val, k ) + Vec_IntWriteEntry( vMap, Par >> 2, k ); + Vec_IntClear( vTemp ); + for ( k = 0; k < pCell[6]; k++ ) + { + int Perm = Vec_IntEntry( vMap, Rtl_WireName(pModel, k) ); + int Par = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)]; + int Val = pCell[CELL_NUM+2*(pCell[4]+pCell[5]+Perm)+1]; + assert( (Par >> 2) == Rtl_WireName(pModel, k) ); + Vec_IntWriteEntry( vMap, Par >> 2, -1 ); + Vec_IntPushTwo( vTemp, Par, Val ); + assert( Perm >= 0 ); + } + memcpy( pCell+CELL_NUM+2*(pCell[4]+pCell[5]), Vec_IntArray(vTemp), sizeof(int)*Vec_IntSize(vTemp) ); + } + Vec_IntForEachEntry( p->pLib->vMap, Value, i ) + assert( Value == -1 ); +} +void Rtl_LibOrderWires( Rtl_Lib_t * pLib ) +{ + Rtl_Ntk_t * p; int i; + if ( pLib->vMap == NULL ) + pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + Rtl_NtkOrderWires( p ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + Rtl_LibUpdateInstances( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig ); + +int Rtl_NtkCountWireRange( Rtl_Ntk_t * p, int NameId ) +{ + int Wire = Rtl_WireMapNameToId( p, NameId ); + int Width = Rtl_WireWidth( p, Wire ); + return Width; +} +int Rtl_NtkCountSliceRange( Rtl_Ntk_t * p, int * pSlice ) +{ + return pSlice[1] - pSlice[2] + 1; +} +int Rtl_NtkCountConcatRange( Rtl_Ntk_t * p, int * pConcat ) +{ + int i, nBits = 0; + for ( i = 1; i <= pConcat[0]; i++ ) + nBits += Rtl_NtkCountSignalRange( p, pConcat[i] ); + return nBits; +} +int Rtl_NtkCountSignalRange( Rtl_Ntk_t * p, int Sig ) +{ + if ( Rtl_SigIsNone(Sig) ) + return Rtl_NtkCountWireRange( p, Sig >> 2 ); + if ( Rtl_SigIsSlice(Sig) ) + return Rtl_NtkCountSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); + if ( Rtl_SigIsConcat(Sig) ) + return Rtl_NtkCountConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); + if ( Rtl_SigIsConst(Sig) ) + assert( 0 ); + return ABC_INFINITY; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig ); + +int Rtl_NtkCheckWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right ) +{ + int Wire = Rtl_WireMapNameToId( p, NameId ); + int First = Rtl_WireBitStart( p, Wire ); + int Width = Rtl_WireWidth( p, Wire ), i; + Left = Left == -1 ? Width-1 : Left; + Right = Right == -1 ? 0 : Right; + assert ( Right <= Left && Right >= 0 ); + for ( i = Right; i <= Left; i++ ) + if ( Vec_IntEntry(&p->vLits, First+i) == -1 ) + return 0; + return 1; +} +int Rtl_NtkCheckSliceRange( Rtl_Ntk_t * p, int * pSlice ) +{ + return Rtl_NtkCheckWireRange( p, pSlice[0], pSlice[1], pSlice[2] ); +} +int Rtl_NtkCheckConcatRange( Rtl_Ntk_t * p, int * pConcat ) +{ + int i; + for ( i = 1; i <= pConcat[0]; i++ ) + if ( !Rtl_NtkCheckSignalRange( p, pConcat[i] ) ) + return 0; + return 1; +} +int Rtl_NtkCheckSignalRange( Rtl_Ntk_t * p, int Sig ) +{ + if ( Rtl_SigIsNone(Sig) ) + return Rtl_NtkCheckWireRange( p, Sig >> 2, -1, -1 ); + else if ( Rtl_SigIsConst(Sig) ) + return 1; + else if ( Rtl_SigIsSlice(Sig) ) + return Rtl_NtkCheckSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); + else if ( Rtl_SigIsConcat(Sig) ) + return Rtl_NtkCheckConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); + else assert( 0 ); + return -1; +} + + +extern void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value ); + +void Rtl_NtkSetWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int Value ) +{ + //char * pName = Rtl_NtkStr( p, NameId ); + int Wire = Rtl_WireMapNameToId( p, NameId ); + int First = Rtl_WireBitStart( p, Wire ); + int Width = Rtl_WireWidth( p, Wire ), i; + Left = Left == -1 ? Width-1 : Left; + Right = Right == -1 ? 0 : Right; + assert ( Right <= Left && Right >= 0 ); + for ( i = Right; i <= Left; i++ ) + { + assert( Vec_IntEntry(&p->vLits, First+i) == -1 ); + Vec_IntWriteEntry(&p->vLits, First+i, Value ); + } + //printf( "Finished setting wire %s\n", Rtl_NtkStr(p, NameId) ); +} +void Rtl_NtkSetSliceRange( Rtl_Ntk_t * p, int * pSlice, int Value ) +{ + Rtl_NtkSetWireRange( p, pSlice[0], pSlice[1], pSlice[2], Value ); +} +void Rtl_NtkSetConcatRange( Rtl_Ntk_t * p, int * pConcat, int Value ) +{ + int i; + for ( i = 1; i <= pConcat[0]; i++ ) + Rtl_NtkSetSignalRange( p, pConcat[i], Value ); +} +void Rtl_NtkSetSignalRange( Rtl_Ntk_t * p, int Sig, int Value ) +{ + if ( Rtl_SigIsNone(Sig) ) + Rtl_NtkSetWireRange( p, Sig >> 2, -1, -1, Value ); + else if ( Rtl_SigIsSlice(Sig) ) + Rtl_NtkSetSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), Value ); + else if ( Rtl_SigIsConcat(Sig) ) + Rtl_NtkSetConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), Value ); + else if ( Rtl_SigIsConst(Sig) ) + assert( 0 ); +} + + +void Rtl_NtkInitInputs( Rtl_Ntk_t * p ) +{ + int b, i; + for ( i = 0; i < p->nInputs; i++ ) + { + int First = Rtl_WireBitStart( p, i ); + int Width = Rtl_WireWidth( p, i ); + for ( b = 0; b < Width; b++ ) + { + assert( Vec_IntEntry(&p->vLits, First+b) == -1 ); + Vec_IntWriteEntry( &p->vLits, First+b, Vec_IntSize(&p->vOrder) ); + } + Vec_IntPush( &p->vOrder, i ); + //printf( "Finished setting input %s\n", Rtl_WireNameStr(p, i) ); + } +} +Vec_Int_t * Rtl_NtkCollectOutputs( Rtl_Ntk_t * p ) +{ + //char * pNtkName = Rtl_NtkName(p); + int b, i; + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + for ( i = 0; i < p->nOutputs; i++ ) + { + //char * pName = Rtl_WireNameStr(p, p->nInputs + i); + int First = Rtl_WireBitStart( p, p->nInputs + i ); + int Width = Rtl_WireWidth( p, p->nInputs + i ); + for ( b = 0; b < Width; b++ ) + { + assert( Vec_IntEntry(&p->vLits, First+b) != -1 ); + Vec_IntPush( vRes, Vec_IntEntry(&p->vLits, First+b) ); + } + } + return vRes; +} +int Rtl_NtkReviewCells( Rtl_Ntk_t * p ) +{ + int i, k, Par, Val, * pCell, RetValue = 0; + Rtl_NtkForEachCell( p, pCell, i ) + { + if ( pCell[7] ) + continue; + Rtl_CellForEachInput( p, pCell, Par, Val, k ) + if ( !Rtl_NtkCheckSignalRange( p, Val ) ) + break; + if ( k < Rtl_CellInputNum(pCell) ) + continue; + Rtl_CellForEachOutput( p, pCell, Par, Val, k ) + Rtl_NtkSetSignalRange( p, Val, Vec_IntSize(&p->vOrder) ); + Vec_IntPush( &p->vOrder, p->nInputs + i ); + pCell[7] = 1; + RetValue = 1; + //printf( "Setting cell %s as propagated.\n", Rtl_CellNameStr(p, pCell) ); + } + return RetValue; +} +int Rtl_NtkReviewConnections( Rtl_Ntk_t * p ) +{ + int i, * pCon, RetValue = 0; + Rtl_NtkForEachCon( p, pCon, i ) + { + int Status0 = Rtl_NtkCheckSignalRange( p, pCon[0] ); + int Status1 = Rtl_NtkCheckSignalRange( p, pCon[1] ); + if ( Status0 == Status1 ) + continue; + if ( !Status0 && Status1 ) + ABC_SWAP( int, pCon[0], pCon[1] ) + Rtl_NtkSetSignalRange( p, pCon[1], Vec_IntSize(&p->vOrder) ); + Vec_IntPush( &p->vOrder, p->nInputs + Rtl_NtkCellNum(p) + i ); + RetValue = 1; + } + return RetValue; +} +void Rtl_NtkPrintCellOrder( Rtl_Ntk_t * p ) +{ + int i, iCell; + Vec_IntForEachEntry( &p->vOrder, iCell, i ) + { + printf( "%4d : ", i ); + printf( "Cell %4d ", iCell ); + if ( iCell < p->nInputs ) + printf( "Type Input " ); + else if ( iCell < p->nInputs + Rtl_NtkCellNum(p) ) + { + int * pCell = Rtl_NtkCell( p, iCell - p->nInputs ); + printf( "Type %4d ", Rtl_CellType(pCell) ); + printf( "%16s ", Rtl_CellTypeStr(p, pCell) ); + printf( "%16s ", Rtl_CellNameStr(p, pCell) ); + } + else + printf( "Type Connection " ); + printf( "\n" ); + } +} +void Rtl_NtkPrintUnusedCells( Rtl_Ntk_t * p ) +{ + int i, * pCell; + printf( "\n*** Printing unused cells:\n" ); + Rtl_NtkForEachCell( p, pCell, i ) + { + if ( pCell[7] ) + continue; + printf( "Unused cell %s %s\n", Rtl_CellTypeStr(p, pCell), Rtl_CellNameStr(p, pCell) ); + } + printf( "\n" ); +} +void Rtl_NtkOrderCells( Rtl_Ntk_t * p ) +{ + Vec_Int_t * vRes; + int nBits = Rtl_NtkRangeWires( p ); + Vec_IntFill( &p->vLits, nBits, -1 ); + + Vec_IntClear( &p->vOrder ); + Vec_IntGrow( &p->vOrder, Rtl_NtkObjNum(p) ); + Rtl_NtkInitInputs( p ); + + Rtl_NtkMapWires( p, 0 ); +//Vec_IntPrint(&p->vLits); + + Rtl_NtkReviewConnections( p ); + while ( Rtl_NtkReviewCells(p) | Rtl_NtkReviewConnections(p) ); + Rtl_NtkMapWires( p, 1 ); + + vRes = Rtl_NtkCollectOutputs( p ); + Vec_IntFree( vRes ); + + //Rtl_NtkPrintCellOrder( p ); +} +void Rtl_LibOrderCells( Rtl_Lib_t * pLib ) +{ + Rtl_Ntk_t * p; int i; + if ( pLib->vMap == NULL ) + pLib->vMap = Vec_IntStartFull( Abc_NamObjNumMax(pLib->pManName) ); + assert( Vec_IntSize(pLib->vMap) == Abc_NamObjNumMax(pLib->pManName) ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + Rtl_NtkOrderCells( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rtl_TokenUnspace( char * p ) +{ + int i, Length = strlen(p), Quote = 0; + for ( i = 0; i < Length; i++ ) + if ( p[i] == '\"' ) + Quote ^= 1; + else if ( Quote && p[i] == ' ' ) + p[i] = '\"'; +} +void Rtl_TokenRespace( char * p ) +{ + int i, Length = strlen(p); + assert( p[0] == '\"' && p[Length-1] == '\"' ); + for ( i = 1; i < Length-1; i++ ) + if ( p[i] == '\"' ) + p[i] = ' '; +} +Vec_Int_t * Rtl_NtkReadFile( char * pFileName, Abc_Nam_t * p ) +{ + Vec_Int_t * vTokens; + char * pTemp, Buffer[MAX_LINE]; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + Abc_NamStrFindOrAdd( p, "module", NULL ); + assert( Abc_NamObjNumMax(p) == 2 ); + vTokens = Vec_IntAlloc( 1000 ); + while ( fgets( Buffer, MAX_LINE, pFile ) != NULL ) + { + if ( Buffer[0] == '#' ) + continue; + Rtl_TokenUnspace( Buffer ); + pTemp = strtok( Buffer, " \t\r\n" ); + if ( pTemp == NULL ) + continue; + while ( pTemp ) + { + if ( *pTemp == '\"' ) Rtl_TokenRespace( pTemp ); + Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, pTemp, NULL) ); + pTemp = strtok( NULL, " \t\r\n" ); + } + Vec_IntPush( vTokens, -1 ); + } + fclose( pFile ); + return vTokens; +} + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig ); + +void Rtl_NtkPrintConst( Rtl_Ntk_t * p, int * pConst ) +{ + int i; + if ( pConst[0] == -1 ) + { + fprintf( Rtl_NtkFile(p), " %d", pConst[1] ); + return; + } + fprintf( Rtl_NtkFile(p), " %d\'", pConst[0] ); + for ( i = pConst[0] - 1; i >= 0; i-- ) + fprintf( Rtl_NtkFile(p), "%d", Abc_InfoHasBit(pConst+1,i) ); +} +void Rtl_NtkPrintSlice( Rtl_Ntk_t * p, int * pSlice ) +{ + fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, pSlice[0]) ); + if ( pSlice[1] == pSlice[2] ) + fprintf( Rtl_NtkFile(p), " [%d]", pSlice[1] ); + else + fprintf( Rtl_NtkFile(p), " [%d:%d]", pSlice[1], pSlice[2] ); +} +void Rtl_NtkPrintConcat( Rtl_Ntk_t * p, int * pConcat ) +{ + int i; + fprintf( Rtl_NtkFile(p), " {" ); + for ( i = 1; i <= pConcat[0]; i++ ) + Rtl_NtkPrintSig( p, pConcat[i] ); + fprintf( Rtl_NtkFile(p), " }" ); +} +void Rtl_NtkPrintSig( Rtl_Ntk_t * p, int Sig ) +{ + if ( Rtl_SigIsNone(Sig) ) + fprintf( Rtl_NtkFile(p), " %s", Rtl_NtkStr(p, Sig >> 2) ); + else if ( Rtl_SigIsConst(Sig) ) + Rtl_NtkPrintConst( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) ); + else if ( Rtl_SigIsSlice(Sig) ) + Rtl_NtkPrintSlice( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); + else if ( Rtl_SigIsConcat(Sig) ) + Rtl_NtkPrintConcat( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); + else assert( 0 ); +} +void Rtl_NtkPrintWire( Rtl_Ntk_t * p, int * pWire ) +{ + fprintf( Rtl_NtkFile(p), " wire" ); + if ( pWire[1] != 1 ) fprintf( Rtl_NtkFile(p), " width %d", pWire[1] ); + if ( pWire[2] != 0 ) fprintf( Rtl_NtkFile(p), " offset %d", pWire[2] ); + if ( pWire[0] & 8 ) fprintf( Rtl_NtkFile(p), " upto" ); + if ( pWire[0] & 1 ) fprintf( Rtl_NtkFile(p), " input %d", pWire[3] ); + if ( pWire[0] & 2 ) fprintf( Rtl_NtkFile(p), " output %d", pWire[3] ); + if ( pWire[0] & 4 ) fprintf( Rtl_NtkFile(p), " signed" ); + fprintf( Rtl_NtkFile(p), " %s\n", Rtl_NtkStr(p, pWire[0] >> 4) ); +} +void Rtl_NtkPrintCell( Rtl_Ntk_t * p, int * pCell ) +{ + int i, Par, Val; + Rtl_CellForEachAttr( p, pCell, Par, Val, i ) + fprintf( Rtl_NtkFile(p), " attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) ); + fprintf( Rtl_NtkFile(p), " cell %s %s\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkStr(p, pCell[1]) ); + Rtl_CellForEachParam( p, pCell, Par, Val, i ) + fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" ); + Rtl_CellForEachConnect( p, pCell, Par, Val, i ) + fprintf( Rtl_NtkFile(p), " connect" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" ); + fprintf( Rtl_NtkFile(p), " end\n" ); +} +void Rtl_NtkPrintConnection( Rtl_Ntk_t * p, int * pCon ) +{ + fprintf( Rtl_NtkFile(p), " connect" ); + Rtl_NtkPrintSig( p, pCon[0] ); + Rtl_NtkPrintSig( p, pCon[1] ); + fprintf( Rtl_NtkFile(p), "\n" ); +} +void Rtl_NtkPrint( Rtl_Ntk_t * p ) +{ + int i, Par, Val, * pWire, * pCell, * pCon; + fprintf( Rtl_NtkFile(p), "\n" ); + Rtl_NtkForEachAttr( p, Par, Val, i ) + fprintf( Rtl_NtkFile(p), "attribute %s %s\n", Rtl_NtkStr(p, Par), Rtl_NtkStr(p, Val) ); + fprintf( Rtl_NtkFile(p), "module %s\n", Rtl_NtkName(p) ); + Rtl_NtkForEachWire( p, pWire, i ) + Rtl_NtkPrintWire( p, pWire ); + Rtl_NtkForEachCell( p, pCell, i ) + Rtl_NtkPrintCell( p, pCell ); + Rtl_NtkForEachCon( p, pCon, i ) + Rtl_NtkPrintConnection( p, pCon ); + fprintf( Rtl_NtkFile(p), "end\n" ); +} +void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p ) +{ + p->pFile = pFileName ? fopen( pFileName, "wb" ) : stdout; + if ( p->pFile == NULL ) + { + printf( "Cannot open output file \"%s\".\n", pFileName ); + return; + } + else + { + Rtl_Ntk_t * pNtk; int i; + fprintf( p->pFile, "\n" ); + fprintf( p->pFile, "# Generated by ABC on %s\n", Extra_TimeStamp() ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + Rtl_NtkPrint( pNtk ); + if ( p->pFile != stdout ) + fclose( p->pFile ); + p->pFile = NULL; + } +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos ); + +int Rtl_NtkReadConst( Rtl_Ntk_t * p, char * pConst ) +{ + Vec_Int_t * vConst = &p->pLib->vConsts; + int RetVal = Vec_IntSize( vConst ); + int Width = atoi( pConst ); + assert( pConst[0] >= '0' && pConst[0] <= '9' ); + if ( strstr(pConst, "\'") ) + { + int Length = strlen(pConst); + int nWords = (Width + 31) / 32; + int i, * pArray; + Vec_IntPush( vConst, Width ); + Vec_IntFillExtra( vConst, Vec_IntSize(vConst) + nWords, 0 ); + pArray = Vec_IntEntryP( vConst, RetVal + 1 ); + for ( i = Length-1; i >= Length-Width; i-- ) + if ( pConst[i] == '1' ) + Abc_InfoSetBit( pArray, Length-1-i ); + } + else + { + Vec_IntPush( vConst, -1 ); + Vec_IntPush( vConst, Width ); + } + return (RetVal << 2) | 1; +} +int Rtl_NtkReadSlice( Rtl_Ntk_t * p, char * pSlice, int NameId ) +{ + Vec_Int_t * vSlice = &p->pLib->vSlices; + int RetVal = Vec_IntSize( vSlice ); + int Left = atoi( pSlice+1 ); + char * pTwo = strstr( pSlice, ":" ); + int Right = pTwo ? atoi( pTwo+1 ) : Left; + assert( pSlice[0] == '[' && pSlice[strlen(pSlice)-1] == ']' ); + Vec_IntPush( vSlice, NameId ); + Vec_IntPush( vSlice, Left ); + Vec_IntPush( vSlice, Right ); + return (RetVal << 2) | 2; +} +int Rtl_NtkReadConcat( Rtl_Ntk_t * p, int * pPos ) +{ + Vec_Int_t * vConcat = &p->pLib->vConcats; + int RetVal = Vec_IntSize( vConcat ); char * pTok; + Vec_IntPush( vConcat, ABC_INFINITY ); + do { + int Sig = Rtl_NtkReadSig( p, pPos ); + Vec_IntPush( vConcat, Sig ); + pTok = Rtl_NtkTokStr( p, *pPos ); + } + while ( pTok[0] != '}' ); + Vec_IntWriteEntry( vConcat, RetVal, Vec_IntSize(vConcat) - RetVal - 1 ); + assert( pTok[0] == '}' ); + (*pPos)++; + return (RetVal << 2) | 3; +} +int Rtl_NtkReadSig( Rtl_Ntk_t * p, int * pPos ) +{ + int NameId = Rtl_NtkTokId( p, *pPos ); + char * pSig = Rtl_NtkTokStr( p, (*pPos)++ ); + if ( pSig[0] >= '0' && pSig[0] <= '9' ) + return Rtl_NtkReadConst( p, pSig ); + if ( pSig[0] == '{' ) + return Rtl_NtkReadConcat( p, pPos ); + else + { + char * pNext = Rtl_NtkTokStr( p, *pPos ); + if ( pNext && pNext[0] == '[' ) + { + (*pPos)++; + return Rtl_NtkReadSlice( p, pNext, NameId ); + } + else + return NameId << 2; + } +} +int Rtl_NtkReadWire( Rtl_Ntk_t * p, int iPos ) +{ + int i, Entry, Prev = -1; + int Width = 1, Upto = 0, Offset = 0, Out = 0, In = 0, Number = 0, Signed = 0; + assert( Rtl_NtkPosCheck(p, iPos-1, RTL_WIRE) ); + Vec_IntClear( &p->pLib->vAttrTemp ); + Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos ) + { + char * pTok = Rtl_NtkTokStr(p, i); + if ( Entry == -1 ) + break; + else if ( Rtl_NtkTokCheck(p, Entry, RTL_WIDTH) ) + Width = atoi( Rtl_NtkTokStr(p, ++i) ); + else if ( Rtl_NtkTokCheck(p, Entry, RTL_OFFSET) ) + Offset = atoi( Rtl_NtkTokStr(p, ++i) ); + else if ( Rtl_NtkTokCheck(p, Entry, RTL_INPUT) ) + Number = atoi( Rtl_NtkTokStr(p, ++i) ), In = 1, p->nInputs++; + else if ( Rtl_NtkTokCheck(p, Entry, RTL_OUTPUT) ) + Number = atoi( Rtl_NtkTokStr(p, ++i) ), Out = 1, p->nOutputs++; + else if ( Rtl_NtkTokCheck(p, Entry, RTL_SIGNED) ) + Signed = 1; + else if ( Rtl_NtkTokCheck(p, Entry, RTL_UPTO) ) + Upto = 1; + Prev = Entry; + } + // add WIRE_NUM=5 entries + Vec_IntPush( &p->vWires, (Prev << 4) | (Upto << 3) | (Signed << 2) | (Out << 1) | (In << 0) ); + Vec_IntPush( &p->vWires, Width ); + Vec_IntPush( &p->vWires, Offset ); + Vec_IntPush( &p->vWires, Number ); + Vec_IntPush( &p->vWires, -1 ); + assert( Rtl_NtkPosCheck(p, i, RTL_NONE) ); + return i; +} +int Rtl_NtkReadAttribute( Rtl_Ntk_t * p, int iPos ) +{ +//char * pTok1 = Rtl_NtkTokStr(p, iPos-1); +//char * pTok2 = Rtl_NtkTokStr(p, iPos); +//char * pTok3 = Rtl_NtkTokStr(p, iPos+1); + assert( Rtl_NtkPosCheck(p, iPos-1, RTL_ATTRIBUTE) ); + Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) ); + Vec_IntPush( &p->pLib->vAttrTemp, Rtl_NtkTokId(p, iPos++) ); + assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) ); + return iPos; +} +int Rtl_NtkReadAttribute2( Rtl_Lib_t * p, int iPos ) +{ +//char * pTok1 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos-1)); +//char * pTok2 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos) ); +//char * pTok3 = Abc_NamStr(p->pManName, Vec_IntEntry(p->vTokens, iPos+1)); + assert( Vec_IntEntry(p->vTokens, iPos-1) == p->pMap[RTL_ATTRIBUTE] ); + Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) ); + Vec_IntPush( &p->vAttrTemp, Vec_IntEntry(p->vTokens, iPos++) ); + assert( Vec_IntEntry(p->vTokens, iPos) == p->pMap[RTL_NONE] ); + return iPos; +} +int Rtl_NtkReadConnect( Rtl_Ntk_t * p, int iPos ) +{ +//char * pTok1 = Rtl_NtkTokStr(p, iPos-1); +//char * pTok2 = Rtl_NtkTokStr(p, iPos); +//char * pTok3 = Rtl_NtkTokStr(p, iPos+1); + assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CONNECT) ); + Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) ); + Vec_IntPush( &p->vConns, Rtl_NtkReadSig(p, &iPos) ); + assert( Rtl_NtkPosCheck(p, iPos, RTL_NONE) ); + return iPos; +} +int Rtl_NtkReadCell( Rtl_Ntk_t * p, int iPos ) +{ + Vec_Int_t * vAttrs = &p->pLib->vAttrTemp; + int iPosPars, iPosCons, Par, Val, i, Entry; + assert( Rtl_NtkPosCheck(p, iPos-1, RTL_CELL) ); + Vec_IntPush( &p->vCells, Vec_IntSize(&p->vStore) ); + Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 0 + Vec_IntPush( &p->vStore, Rtl_NtkTokId(p, iPos++) ); // 1 + Vec_IntPush( &p->vStore, -1 ); + Vec_IntPush( &p->vStore, -1 ); + assert( Vec_IntSize(vAttrs) % 2 == 0 ); + Vec_IntPush( &p->vStore, Vec_IntSize(vAttrs)/2 ); + iPosPars = Vec_IntSize(&p->vStore); + Vec_IntPush( &p->vStore, 0 ); // 5 + iPosCons = Vec_IntSize(&p->vStore); + Vec_IntPush( &p->vStore, 0 ); // 6 + Vec_IntPush( &p->vStore, 0 ); // 7 + assert( Vec_IntSize(&p->vStore) == Vec_IntEntryLast(&p->vCells)+CELL_NUM ); + Vec_IntAppend( &p->vStore, vAttrs ); + Vec_IntClear( vAttrs ); + Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos ) + { + if ( Rtl_NtkTokCheck(p, Entry, RTL_END) ) + break; + if ( Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) || Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) ) + { + int iPosCount = Rtl_NtkTokCheck(p, Entry, RTL_PARAMETER) ? iPosPars : iPosCons; + Vec_IntAddToEntry( &p->vStore, iPosCount, 1 ); + i++; + Par = Rtl_NtkReadSig(p, &i); + Val = Rtl_NtkReadSig(p, &i); + Vec_IntPushTwo( &p->vStore, Par, Val ); + } + assert( Rtl_NtkPosCheck(p, i, RTL_NONE) ); + } + assert( Rtl_NtkPosCheck(p, i, RTL_END) ); + i++; + assert( Rtl_NtkPosCheck(p, i, RTL_NONE) ); + return i; +} +int Wln_ReadMatchEnd( Rtl_Ntk_t * p, int Mod ) +{ + int i, Entry, Count = 0; + Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, Mod ) + if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) ) + Count++; + else if ( Rtl_NtkTokCheck(p, Entry, RTL_END) ) + { + if ( Count == 0 ) + return i; + Count--; + } + assert( 0 ); + return -1; +} +int Rtl_NtkReadNtk( Rtl_Lib_t * pLib, int Mod ) +{ + Rtl_Ntk_t * p = Rtl_NtkAlloc( pLib ); + Vec_Int_t * vAttrs = &p->pLib->vAttrTemp; + int End = Wln_ReadMatchEnd( p, Mod ), i, Entry; + assert( Rtl_NtkPosCheck(p, Mod-1, RTL_MODULE) ); + assert( Rtl_NtkPosCheck(p, End, RTL_END) ); + p->NameId = Rtl_NtkTokId( p, Mod ); + p->Slice0 = Vec_IntSize( &pLib->vSlices ); + Vec_IntAppend( &p->vAttrs, vAttrs ); + Vec_IntClear( vAttrs ); + Vec_IntForEachEntryStartStop( pLib->vTokens, Entry, i, Mod, End ) + { + if ( Rtl_NtkTokCheck(p, Entry, RTL_WIRE) ) + i = Rtl_NtkReadWire( p, i+1 ); + else if ( Rtl_NtkTokCheck(p, Entry, RTL_ATTRIBUTE) ) + i = Rtl_NtkReadAttribute( p, i+1 ); + else if ( Rtl_NtkTokCheck(p, Entry, RTL_CELL) ) + i = Rtl_NtkReadCell( p, i+1 ); + else if ( Rtl_NtkTokCheck(p, Entry, RTL_CONNECT) ) + i = Rtl_NtkReadConnect( p, i+1 ); + } + p->Slice1 = Vec_IntSize( &pLib->vSlices ); + assert( Vec_IntSize(&p->vWires) % WIRE_NUM == 0 ); + return End; +} +void Rtl_NtkReportUndefs( Rtl_Ntk_t * p ) +{ + Vec_Int_t * vNames, * vCounts; + int i, iName, * pCell, nUndef = 0; + vNames = Vec_IntAlloc( 10 ); + vCounts = Vec_IntAlloc( 10 ); + Rtl_NtkForEachCell( p, pCell, i ) + if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 ) + { + iName = Vec_IntFind(vNames, Rtl_CellType(pCell)); + if ( iName == -1 ) + { + iName = Vec_IntSize(vNames); + Vec_IntPush( vNames, Rtl_CellType(pCell) ); + Vec_IntPush( vCounts, 0 ); + } + Vec_IntAddToEntry( vCounts, iName, 1 ); + } + Vec_IntForEachEntry( vNames, iName, i ) + printf( " %s (%d)", Rtl_NtkStr(p, iName), Vec_IntEntry(vCounts, i) ); + printf( "\n" ); + Vec_IntFree( vNames ); + Vec_IntFree( vCounts ); +} +int Rtl_NtkSetParents( Rtl_Ntk_t * p ) +{ + int i, * pCell, nUndef = 0; + Rtl_NtkForEachCell( p, pCell, i ) + { + pCell[2] = Rtl_NtkReadType( p, Rtl_CellType(pCell) ); + if ( Rtl_CellModule(pCell) == ABC_INFINITY-1 ) + nUndef++; + else + pCell[3] = Rtl_CellModule(pCell) < ABC_INFINITY ? pCell[6]-1 : Rtl_NtkModule(p, Rtl_CellModule(pCell)-ABC_INFINITY)->nInputs; + } + if ( !nUndef ) + return 0; + printf( "Module \"%s\" has %d blackbox instances: ", Rtl_NtkName(p), nUndef ); + Rtl_NtkReportUndefs( p ); + return nUndef; +} +void Rtl_LibSetParents( Rtl_Lib_t * p ) +{ + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + Rtl_NtkSetParents( pNtk ); +} +void Rtl_LibReorderModules_rec( Rtl_Ntk_t * p, Vec_Ptr_t * vNew ) +{ + int i, * pCell; + Rtl_NtkForEachCell( p, pCell, i ) + { + Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell ); + if ( pMod && pMod->iCopy == -1 ) + Rtl_LibReorderModules_rec( pMod, vNew ); + } + assert( p->iCopy == -1 ); + p->iCopy = Vec_PtrSize(vNew); + Vec_PtrPush( vNew, p ); +} +void Rtl_NtkUpdateBoxes( Rtl_Ntk_t * p ) +{ + int i, * pCell; + Rtl_NtkForEachCell( p, pCell, i ) + { + Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell ); + if ( pMod ) + pCell[2] = ABC_INFINITY + pMod->iCopy; + } +} +void Rtl_LibUpdateBoxes( Rtl_Lib_t * p ) +{ + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + Rtl_NtkUpdateBoxes( pNtk ); +} +void Rtl_LibReorderModules( Rtl_Lib_t * p ) +{ + Vec_Ptr_t * vNew = Vec_PtrAlloc( Vec_PtrSize(p->vNtks) ); + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->iCopy = -1; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + if ( pNtk->iCopy == -1 ) + Rtl_LibReorderModules_rec( pNtk, vNew ); + assert( Vec_PtrSize(p->vNtks) == Vec_PtrSize(vNew) ); + Rtl_LibUpdateBoxes( p ); + Vec_PtrClear( p->vNtks ); + Vec_PtrAppend( p->vNtks, vNew ); + Vec_PtrFree( vNew ); +} +Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec ) +{ + Rtl_Lib_t * p = Rtl_LibAlloc(); int i, Entry; + p->pSpec = Abc_UtilStrsav( pFileSpec ); + p->pManName = Abc_NamStart( 1000, 50 ); + p->vTokens = Rtl_NtkReadFile( pFileName, p->pManName ); + Rtl_LibDeriveMap( p ); + Vec_IntClear( &p->vAttrTemp ); + Vec_IntForEachEntry( p->vTokens, Entry, i ) + if ( Entry == p->pMap[RTL_MODULE] ) + i = Rtl_NtkReadNtk( p, i+1 ); + else if ( Entry == p->pMap[RTL_ATTRIBUTE] ) + i = Rtl_NtkReadAttribute2( p, i+1 ); + Rtl_LibSetParents( p ); + Rtl_LibReorderModules( p ); + return p; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig ); + +void Rtl_NtkCollectWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right ) +{ + int Wire = Rtl_WireMapNameToId( p, NameId ); + int First = Rtl_WireBitStart( p, Wire ); + int Width = Rtl_WireWidth( p, Wire ), i; + Left = Left == -1 ? Width-1 : Left; + Right = Right == -1 ? 0 : Right; + assert ( Right >= 0 && Right <= Left ); + for ( i = Right; i <= Left; i++ ) + { + assert( Vec_IntEntry(&p->vLits, First+i) != -1 ); + Vec_IntPush( &p->vBitTemp, Vec_IntEntry(&p->vLits, First+i) ); + } +} +void Rtl_NtkCollectConstRange( Rtl_Ntk_t * p, int * pConst ) +{ + int i, nLimit = pConst[0]; + if ( nLimit == -1 ) + nLimit = 32; + //assert( pConst[0] > 0 ); + for ( i = 0; i < nLimit; i++ ) + Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit(pConst+1,i) ); +} +void Rtl_NtkCollectSliceRange( Rtl_Ntk_t * p, int * pSlice ) +{ + Rtl_NtkCollectWireRange( p, pSlice[0], pSlice[1], pSlice[2] ); +} +void Rtl_NtkCollectConcatRange( Rtl_Ntk_t * p, int * pConcat ) +{ + int i; + for ( i = pConcat[0]; i >= 1; i-- ) + Rtl_NtkCollectSignalRange( p, pConcat[i] ); +} +void Rtl_NtkCollectSignalRange( Rtl_Ntk_t * p, int Sig ) +{ + if ( Rtl_SigIsNone(Sig) ) + Rtl_NtkCollectWireRange( p, Sig >> 2, -1, -1 ); + else if ( Rtl_SigIsConst(Sig) ) + Rtl_NtkCollectConstRange( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) ); + else if ( Rtl_SigIsSlice(Sig) ) + Rtl_NtkCollectSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); + else if ( Rtl_SigIsConcat(Sig) ) + Rtl_NtkCollectConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); + else assert( 0 ); +} + + +extern int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits ); + +int Rtl_NtkInsertWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int * pLits, int nLits ) +{ + //char * pName = Rtl_NtkStr( p, NameId ); + int Wire = Rtl_WireMapNameToId( p, NameId ); + int First = Rtl_WireBitStart( p, Wire ); + int Width = Rtl_WireWidth( p, Wire ), i, k = 0; + Left = Left == -1 ? Width-1 : Left; + Right = Right == -1 ? 0 : Right; + assert ( Right >= 0 && Right <= Left ); + for ( i = Right; i <= Left; i++ ) + { + assert( Vec_IntEntry(&p->vLits, First+i) == -1 ); + Vec_IntWriteEntry(&p->vLits, First+i, pLits[k++] ); + } + assert( k <= nLits ); + return k; +} +int Rtl_NtkInsertSliceRange( Rtl_Ntk_t * p, int * pSlice, int * pLits, int nLits ) +{ + return Rtl_NtkInsertWireRange( p, pSlice[0], pSlice[1], pSlice[2], pLits, nLits ); +} +int Rtl_NtkInsertConcatRange( Rtl_Ntk_t * p, int * pConcat, int * pLits, int nLits ) +{ + int i, k = 0; + for ( i = 1; i <= pConcat[0]; i++ ) + k += Rtl_NtkInsertSignalRange( p, pConcat[i], pLits+k, nLits-k ); + assert( k <= nLits ); + return k; +} +int Rtl_NtkInsertSignalRange( Rtl_Ntk_t * p, int Sig, int * pLits, int nLits ) +{ + int nBits = ABC_INFINITY; + if ( Rtl_SigIsNone(Sig) ) + nBits = Rtl_NtkInsertWireRange( p, Sig >> 2, -1, -1, pLits, nLits ); + if ( Rtl_SigIsSlice(Sig) ) + nBits = Rtl_NtkInsertSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), pLits, nLits ); + if ( Rtl_SigIsConcat(Sig) ) + nBits = Rtl_NtkInsertConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), pLits, nLits ); + if ( Rtl_SigIsConst(Sig) ) + assert( 0 ); + assert( nBits == nLits ); + return nBits; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rtl_NtkBlastInputs( Gia_Man_t * pNew, Rtl_Ntk_t * p ) +{ + int b, i; + for ( i = 0; i < p->nInputs; i++ ) + { + int First = Rtl_WireBitStart( p, i ); + int Width = Rtl_WireWidth( p, i ); + for ( b = 0; b < Width; b++ ) + { + assert( Vec_IntEntry(&p->vLits, First+b) == -1 ); + Vec_IntWriteEntry( &p->vLits, First+b, Gia_ManAppendCi(pNew) ); + } + } +} +void Rtl_NtkBlastOutputs( Gia_Man_t * pNew, Rtl_Ntk_t * p ) +{ + int b, i; + for ( i = 0; i < p->nOutputs; i++ ) + { + int First = Rtl_WireBitStart( p, p->nInputs + i ); + int Width = Rtl_WireWidth( p, p->nInputs + i ); + for ( b = 0; b < Width; b++ ) + { + assert( Vec_IntEntry(&p->vLits, First+b) != -1 ); + Gia_ManAppendCo( pNew, Vec_IntEntry(&p->vLits, First+b) ); + } + } +} +void Rtl_NtkBlastConnect( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCon ) +{ + int nBits; + Vec_IntClear( &p->vBitTemp ); + Rtl_NtkCollectSignalRange( p, pCon[0] ); + nBits = Rtl_NtkInsertSignalRange( p, pCon[1], Vec_IntArray(&p->vBitTemp), Vec_IntSize(&p->vBitTemp) ); + assert( nBits == Vec_IntSize(&p->vBitTemp) ); + //printf( "Finished blasting connection (Value = %d).\n", Vec_IntEntry(&p->vBitTemp, 0) ); +} +void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) +{ + extern Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ); + extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ); + Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); + int k, Par, Val, nBits = 0; + Vec_IntClear( &p->vBitTemp ); + Rtl_CellForEachInput( p, pCell, Par, Val, k ) + Rtl_NtkCollectSignalRange( p, Val ); +// if ( pModel->pGia == NULL ) +// pModel->pGia = Rtl_NtkBlast( pModel ); + assert( pModel->pGia ); + Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp ); + Rtl_CellForEachOutput( p, pCell, Par, Val, k ) + nBits += Rtl_NtkInsertSignalRange( p, Val, Vec_IntArray(&p->vBitTemp)+nBits, Vec_IntSize(&p->vBitTemp)-nBits ); + assert( nBits == Vec_IntSize(&p->vBitTemp) ); +} + +int Rtl_NtkCellParamValue( Rtl_Ntk_t * p, int * pCell, char * pParam ) +{ + int ParamId = Rtl_NtkStrId( p, pParam ); + int i, Par, Val, ValOut = ABC_INFINITY, * pConst; +// p->pLib->pFile = stdout; +// Rtl_CellForEachParam( p, pCell, Par, Val, i ) +// fprintf( Rtl_NtkFile(p), " parameter" ), Rtl_NtkPrintSig(p, Par), Rtl_NtkPrintSig(p, Val), printf( "\n" ); + Rtl_CellForEachParam( p, pCell, Par, Val, i ) + if ( (Par >> 2) == ParamId ) + { + assert( Rtl_SigIsConst(Val) ); + pConst = Vec_IntEntryP( &p->pLib->vConsts, Val >> 2 ); + assert( pConst[0] < 32 ); + ValOut = pConst[1]; + } + return ValOut; +} +void Rtl_NtkBlastOperator( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) +{ + extern void Rtl_NtkBlastNode( Gia_Man_t * pNew, int Type, int nIns, Vec_Int_t * vDatas, int nRange, int fSign0, int fSign1 ); + Vec_Int_t * vRes = &p->pLib->vTemp[3]; + int i, Par, Val, ValOut = -1, nBits = 0, nRange = -1; + int fSign0 = Rtl_NtkCellParamValue( p, pCell, "\\A_SIGNED" ); + int fSign1 = Rtl_NtkCellParamValue( p, pCell, "\\B_SIGNED" ); + Rtl_CellForEachOutput( p, pCell, Par, ValOut, i ) + nRange = Rtl_NtkCountSignalRange( p, ValOut ); + assert( nRange > 0 ); + for ( i = 0; i < TEMP_NUM; i++ ) + Vec_IntClear( &p->pLib->vTemp[i] ); + //printf( "Starting blasting cell %s.\n", Rtl_CellNameStr(p, pCell) ); + Rtl_CellForEachInput( p, pCell, Par, Val, i ) + { + Vec_IntClear( &p->vBitTemp ); + Rtl_NtkCollectSignalRange( p, Val ); + Vec_IntAppend( &p->pLib->vTemp[i], &p->vBitTemp ); + } + Rtl_NtkBlastNode( pNew, Rtl_CellModule(pCell), Rtl_CellInputNum(pCell), p->pLib->vTemp, nRange, fSign0, fSign1 ); + assert( Vec_IntSize(vRes) > 0 ); + nBits = Rtl_NtkInsertSignalRange( p, ValOut, Vec_IntArray(vRes)+nBits, Vec_IntSize(vRes)-nBits ); + assert( nBits == Vec_IntSize(vRes) ); + //printf( "Finished blasting cell %s (Value = %d).\n", Rtl_CellNameStr(p, pCell), Vec_IntEntry(vRes, 0) ); +} +Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) +{ + Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); + int i, iObj, * pCell, nBits = Rtl_NtkRangeWires( p ); + char Buffer[100]; static int counter = 0; + Vec_IntFill( &p->vLits, nBits, -1 ); + Rtl_NtkMapWires( p, 0 ); + Rtl_NtkBlastInputs( pNew, p ); + Gia_ManHashAlloc( pNew ); + Vec_IntForEachEntry( &p->vOrder, iObj, i ) + { + iObj -= Rtl_NtkInputNum(p); + if ( iObj < 0 ) + continue; + if ( iObj >= Rtl_NtkCellNum(p) ) + { + Rtl_NtkBlastConnect( pNew, p, Rtl_NtkCon(p, iObj - Rtl_NtkCellNum(p)) ); + continue; + } + pCell = Rtl_NtkCell(p, iObj); + if ( Rtl_CellModule(pCell) >= ABC_INFINITY ) + Rtl_NtkBlastHierarchy( pNew, p, pCell ); + else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST ) + Rtl_NtkBlastOperator( pNew, p, pCell ); + else + printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) ); + } + Gia_ManHashStop( pNew ); + Rtl_NtkBlastOutputs( pNew, p ); + Rtl_NtkMapWires( p, 1 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + +sprintf( Buffer, "temp%d.aig", counter++ ); +//sprintf( Buffer, "temp%d.aig", counter ); +Gia_AigerWrite( pNew, Buffer, 0, 0, 0 ); +printf( "Dumpted blasted AIG into file \"%s\" for module \"%s\".\n", Buffer, Rtl_NtkName(p) ); +Gia_ManPrintStats( pNew, NULL ); + return pNew; +} +void Rtl_LibBlast( Rtl_Lib_t * pLib ) +{ + Rtl_Ntk_t * p; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + if ( p->pGia == NULL ) + p->pGia = Rtl_NtkBlast( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rtl_LibPreprocess( Rtl_Lib_t * pLib ) +{ + abctime clk = Abc_Clock(); + Rtl_Ntk_t * p1, * p2, * p; + int i, k, Status, fFound = 0; + printf( "Performing preprocessing for verification.\n" ); + // find similar modules + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p1, i ) + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p2, k ) + { + if ( i >= k ) + continue; + if ( Gia_ManCiNum(p1->pGia) != Gia_ManCiNum(p2->pGia) || + Gia_ManCoNum(p1->pGia) != Gia_ManCoNum(p2->pGia) ) + continue; + // two similar modules + Status = Cec_ManVerifyTwo( p1->pGia, p2->pGia, 0 ); + if ( Status != 1 ) + continue; + printf( "Proved equivalent modules: %s == %s\n", Rtl_NtkName(p1), Rtl_NtkName(p2) ); + // inline + if ( Gia_ManAndNum(p1->pGia) > Gia_ManAndNum(p2->pGia) ) + ABC_SWAP( Gia_Man_t *, p1->pGia, p2->pGia ); + assert( Gia_ManAndNum(p1->pGia) <= Gia_ManAndNum(p2->pGia) ); + Gia_ManStopP( &p2->pGia ); + p2->pGia = Gia_ManDup( p1->pGia ); + fFound = 1; + goto finish; + } +finish: + if ( fFound == 0 ) + printf( "Preprocessing not succeded.\n" ); + Abc_PrintTime( 1, "Preprocessing time", Abc_Clock() - clk ); + // blast AIGs again + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + if ( p != p1 && p != p2 ) + Gia_ManStopP( &p->pGia ); + Rtl_LibBlast( pLib ); +} +void Rtl_LibSolve( Rtl_Lib_t * pLib ) +{ + abctime clk = Abc_Clock(); int Status; + Rtl_Ntk_t * pTop = Rtl_LibTop( pLib ); + Gia_Man_t * pCopy = Gia_ManDup( pTop->pGia ); + Gia_ManInvertPos( pCopy ); + Gia_ManAppendCo( pCopy, 0 ); + Status = Cec_ManVerifySimple( pCopy ); + Gia_ManStop( pCopy ); + if ( Status == 1 ) + printf( "Verification problem solved! " ); + else + printf( "Verification problem is NOT solved! " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index aff88af99..89680bbdf 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -37,21 +37,6 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Wln_Ntk_t * Wln_ReadRtl( char * pFileName ) -{ - return NULL; -} /**Function************************************************************* @@ -96,28 +81,31 @@ int Wln_ConvertToRtl( char * pCommand, char * pFileTemp ) fclose( pFile ); return 1; } -Wln_Ntk_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fVerbose ) +Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose ) { - Wln_Ntk_t * pNtk = NULL; + Rtl_Lib_t * pNtk = NULL; char Command[1000]; char * pFileTemp = "_temp_.rtlil"; int fSVlog = strstr(pFileName, ".sv") != NULL; - sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; write_rtlil %s\"", + if ( strstr(pFileName, ".rtl") ) + return Rtl_LibReadFile( pFileName, pFileName ); + sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; %sproc; write_rtlil %s\"", Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName, - pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", pFileTemp ); + pTopModule ? "-top " : "-auto-top", + pTopModule ? pTopModule : "", + fCollapse ? "flatten; " : "", + pFileTemp ); if ( fVerbose ) printf( "%s\n", Command ); if ( !Wln_ConvertToRtl(Command, pFileTemp) ) - { return NULL; - } - pNtk = Wln_ReadRtl( pFileTemp ); + pNtk = Rtl_LibReadFile( pFileTemp, pFileName ); if ( pNtk == NULL ) { printf( "Dumped the design into file \"%s\".\n", pFileTemp ); return NULL; } - unlink( pFileTemp ); + //unlink( pFileTemp ); return pNtk; } Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ) @@ -125,10 +113,16 @@ Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSk Gia_Man_t * pGia = NULL; char Command[1000]; char * pFileTemp = "_temp_.aig"; - int fSVlog = strstr(pFileName, ".sv") != NULL; - sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"", - Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName, - pTopModule ? "-top " : "-auto-top", pTopModule ? pTopModule : "", fTechMap ? "techmap; setundef -zero; " : "", pFileTemp ); + int fRtlil = strstr(pFileName, ".rtl") != NULL; + int fSVlog = strstr(pFileName, ".sv") != NULL; + sprintf( Command, "%s -qp \"%s%s%s; hierarchy %s%s; flatten; proc; %saigmap; write_aiger %s\"", + Wln_GetYosysName(), + fRtlil ? "read_rtlil" : "read_verilog", + fSVlog ? " -sv ":" ", + pFileName, + pTopModule ? "-top " : "-auto-top", + pTopModule ? pTopModule : "", + fTechMap ? "techmap; setundef -zero; " : "", pFileTemp ); if ( fVerbose ) printf( "%s\n", Command ); if ( !Wln_ConvertToRtl(Command, pFileTemp) ) From d892e63256063ba04f20ca347121116bc67a30e2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jan 2022 11:13:18 -0800 Subject: [PATCH 16/74] Compiler warnings. --- src/base/wln/wlnRead.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 492005fdb..71b1b98c6 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -953,7 +953,7 @@ void Rtl_NtkPrintConst( Rtl_Ntk_t * p, int * pConst ) } fprintf( Rtl_NtkFile(p), " %d\'", pConst[0] ); for ( i = pConst[0] - 1; i >= 0; i-- ) - fprintf( Rtl_NtkFile(p), "%d", Abc_InfoHasBit(pConst+1,i) ); + fprintf( Rtl_NtkFile(p), "%d", Abc_InfoHasBit((unsigned *)pConst+1,i) ); } void Rtl_NtkPrintSlice( Rtl_Ntk_t * p, int * pSlice ) { @@ -1079,7 +1079,7 @@ int Rtl_NtkReadConst( Rtl_Ntk_t * p, char * pConst ) pArray = Vec_IntEntryP( vConst, RetVal + 1 ); for ( i = Length-1; i >= Length-Width; i-- ) if ( pConst[i] == '1' ) - Abc_InfoSetBit( pArray, Length-1-i ); + Abc_InfoSetBit( (unsigned *)pArray, Length-1-i ); } else { @@ -1145,7 +1145,7 @@ int Rtl_NtkReadWire( Rtl_Ntk_t * p, int iPos ) Vec_IntClear( &p->pLib->vAttrTemp ); Vec_IntForEachEntryStart( p->pLib->vTokens, Entry, i, iPos ) { - char * pTok = Rtl_NtkTokStr(p, i); + //char * pTok = Rtl_NtkTokStr(p, i); if ( Entry == -1 ) break; else if ( Rtl_NtkTokCheck(p, Entry, RTL_WIDTH) ) @@ -1288,7 +1288,7 @@ int Rtl_NtkReadNtk( Rtl_Lib_t * pLib, int Mod ) void Rtl_NtkReportUndefs( Rtl_Ntk_t * p ) { Vec_Int_t * vNames, * vCounts; - int i, iName, * pCell, nUndef = 0; + int i, iName, * pCell; vNames = Vec_IntAlloc( 10 ); vCounts = Vec_IntAlloc( 10 ); Rtl_NtkForEachCell( p, pCell, i ) @@ -1429,7 +1429,7 @@ void Rtl_NtkCollectConstRange( Rtl_Ntk_t * p, int * pConst ) nLimit = 32; //assert( pConst[0] > 0 ); for ( i = 0; i < nLimit; i++ ) - Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit(pConst+1,i) ); + Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i) ); } void Rtl_NtkCollectSliceRange( Rtl_Ntk_t * p, int * pSlice ) { @@ -1671,7 +1671,7 @@ void Rtl_LibBlast( Rtl_Lib_t * pLib ) void Rtl_LibPreprocess( Rtl_Lib_t * pLib ) { abctime clk = Abc_Clock(); - Rtl_Ntk_t * p1, * p2, * p; + Rtl_Ntk_t * p1 = NULL, * p2 = NULL, * p; int i, k, Status, fFound = 0; printf( "Performing preprocessing for verification.\n" ); // find similar modules From 5b8fa41ba966271f97f99860b21eee83bf51e61a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jan 2022 11:33:53 -0800 Subject: [PATCH 17/74] Suggested bug fixes in the old code. --- src/aig/aig/aigUtil.c | 2 +- src/aig/gia/giaCex.c | 2 +- src/aig/ioa/ioaReadAig.c | 2 +- src/base/abci/abcExact.c | 2 +- src/base/wlc/wlcMem.c | 2 +- src/map/amap/amapUniq.c | 7 +++---- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/aig/aig/aigUtil.c b/src/aig/aig/aigUtil.c index 52f9a184b..68be112f1 100644 --- a/src/aig/aig/aigUtil.c +++ b/src/aig/aig/aigUtil.c @@ -1333,7 +1333,7 @@ void Aig_ManCounterExampleValueStart( Aig_Man_t * pAig, Abc_Cex_t * pCex ) pAig->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Aig_ManObjNumMax(pAig) ) ); // the register values in the counter-example should be zero Saig_ManForEachLo( pAig, pObj, k ) - assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 ); + assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++; // iterate through the timeframes nObjs = Aig_ManObjNumMax(pAig); for ( i = 0; i <= pCex->iFrame; i++ ) diff --git a/src/aig/gia/giaCex.c b/src/aig/gia/giaCex.c index b0e72284f..d12418730 100644 --- a/src/aig/gia/giaCex.c +++ b/src/aig/gia/giaCex.c @@ -195,7 +195,7 @@ void Gia_ManCounterExampleValueStart( Gia_Man_t * pGia, Abc_Cex_t * pCex ) pGia->pData2 = ABC_CALLOC( unsigned, Abc_BitWordNum( (pCex->iFrame + 1) * Gia_ManObjNum(pGia) ) ); // the register values in the counter-example should be zero Gia_ManForEachRo( pGia, pObj, k ) - assert( Abc_InfoHasBit(pCex->pData, iBit++) == 0 ); + assert( Abc_InfoHasBit(pCex->pData, iBit) == 0 ), iBit++; // iterate through the timeframes nObjs = Gia_ManObjNum(pGia); for ( i = 0; i <= pCex->iFrame; i++ ) diff --git a/src/aig/ioa/ioaReadAig.c b/src/aig/ioa/ioaReadAig.c index 1d1dcbe2a..c1eceef01 100644 --- a/src/aig/ioa/ioaReadAig.c +++ b/src/aig/ioa/ioaReadAig.c @@ -438,7 +438,7 @@ Aig_Man_t * Ioa_ReadAiger( char * pFileName, int fCheck ) // read the file into the buffer nFileSize = Ioa_FileSize( pFileName ); pFile = fopen( pFileName, "rb" ); - pContents = ABC_ALLOC( char, nFileSize ); + pContents = ABC_CALLOC( char, nFileSize+1 ); RetValue = fread( pContents, nFileSize, 1, pFile ); fclose( pFile ); diff --git a/src/base/abci/abcExact.c b/src/base/abci/abcExact.c index 42cf11c57..64225c61d 100644 --- a/src/base/abci/abcExact.c +++ b/src/base/abci/abcExact.c @@ -1034,7 +1034,7 @@ static word * Ses_ManDeriveTruth( Ses_Man_t * pSes, char * pSol, int fInvert ) for ( i = 0; i < nGates; ++i ) { f = *p++; - assert( *p++ == 2 ); + assert( *p == 2 ), p++; j = *p++; k = *p++; diff --git a/src/base/wlc/wlcMem.c b/src/base/wlc/wlcMem.c index da0fc8465..b2d5c5ee0 100644 --- a/src/base/wlc/wlcMem.c +++ b/src/base/wlc/wlcMem.c @@ -800,7 +800,7 @@ void Wlc_NtkTrace_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, int iFrame, Vec_Int_t * { int Index = 3*(iFrame*Vec_IntSize(vMemObjs) + iNum); int Value = (int)Vec_WrdEntry( vValues, Index ); - assert( Value == 0 && Value == 1 ); + assert( Value == 0 || Value == 1 ); Wlc_NtkTrace_rec( p, Value ? Wlc_ObjFanin2(p, pObj) : Wlc_ObjFanin1(p, pObj), iFrame, vMemObjs, vValues, ValueA, vRes ); Vec_IntPush( vRes, (iObj << 11) | (iFrame << 1) | Value ); } diff --git a/src/map/amap/amapUniq.c b/src/map/amap/amapUniq.c index dd858c96f..e2be4343a 100644 --- a/src/map/amap/amapUniq.c +++ b/src/map/amap/amapUniq.c @@ -278,15 +278,14 @@ Abc_Lit2Var(iFan2), (Abc_LitIsCompl(iFan2)?'-':'+') ); int ** Amap_LibLookupTableAlloc( Vec_Ptr_t * vVec, int fVerbose ) { Vec_Int_t * vOne; - int ** pRes, * pBuffer; + int ** pRes; int i, k, nTotal, nSize, nEntries, Value; // count the total size nEntries = nSize = Vec_PtrSize( vVec ); Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i ) nEntries += Vec_IntSize(vOne); - pBuffer = ABC_ALLOC( int, nSize * sizeof(void *) + nEntries ); - pRes = (int **)pBuffer; - pRes[0] = pBuffer + nSize * sizeof(void *); + pRes = (int **)ABC_ALLOC( char, nSize * sizeof(void *) + nEntries * sizeof(int) ); + pRes[0] = (int *)((char *)pRes + nSize * sizeof(void *)); nTotal = 0; Vec_PtrForEachEntry( Vec_Int_t *, vVec, vOne, i ) { From 554a1693ac2bd81169b28227ea718527136f5e7e Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Fri, 21 Jan 2022 22:51:36 +0200 Subject: [PATCH 18/74] Move CI to GitHub Actions. Also, a few minor changes that are required to compile ABC under moder compilers. --- .appveyor.yml | 39 ------------------ .github/workflows/build-posix.yml | 62 +++++++++++++++++++++++++++++ .github/workflows/build-windows.yml | 48 ++++++++++++++++++++++ .travis.yml | 36 ----------------- Makefile | 4 +- README.md | 4 +- src/base/acb/acbTest.c | 2 +- src/proof/cec/cecSolveG.c | 2 +- src/sat/msat/msatClause.c | 2 +- src/sat/msat/msatSolverSearch.c | 10 ++--- 10 files changed, 122 insertions(+), 87 deletions(-) delete mode 100644 .appveyor.yml create mode 100644 .github/workflows/build-posix.yml create mode 100644 .github/workflows/build-windows.yml delete mode 100644 .travis.yml diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index c706ed8c1..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: '{build}' - -environment: - - matrix: - - - APPVEYOR_BUILD_WORKER_IMAGE: "Visual Studio 2017" - VCVARS_SCRIPT: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Auxiliary\\Build\\vcvarsall.bat" - VCVARS_PLATFORM: x86 - -init: - - - cmd: '"%VCVARS_SCRIPT%" %VCVARS_PLATFORM%' - -build_script: - - - cmd: | - sed -i 's#ABC_USE_PTHREADS"#ABC_DONT_USE_PTHREADS" /D "_XKEYCHECK_H"#g' *.dsp - awk 'BEGIN { del=0; } /# Begin Group "uap"/ { del=1; } /# End Group/ { if( del > 0 ) {del=0; next;} } del==0 {print;} ' abclib.dsp > tmp.dsp - copy tmp.dsp abclib.dsp - del tmp.dsp - unix2dos *.dsp - - - cmd: | - appveyor PushArtifact abcspace.dsw - appveyor PushArtifact abclib.dsp - appveyor PushArtifact abcexe.dsp - - - cmd: | - devenv abcspace.dsw /upgrade || dir - appveyor PushArtifact UpgradeLog.htm - msbuild abcspace.sln /m /nologo /p:Configuration=Release - - - cmd: | - _TEST\abc.exe -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec" - - - cmd: | - appveyor PushArtifact _TEST/abc.exe - diff --git a/.github/workflows/build-posix.yml b/.github/workflows/build-posix.yml new file mode 100644 index 000000000..aa97aca20 --- /dev/null +++ b/.github/workflows/build-posix.yml @@ -0,0 +1,62 @@ +on: [push] + +jobs: + + build-posix: + strategy: + matrix: + os: [macos-latest, ubuntu-latest] + use_namespace: [false, true] + + runs-on: ${{ matrix.os }} + + env: + MAKE_ARGS: ${{ matrix.use_namespace && 'ABC_USE_NAMESPACE=xxx' || '' }} + DEMO_ARGS: ${{ matrix.use_namespace && '-DABC_NAMESPACE=xxx' || '' }} + DEMO_GCC: ${{ matrix.use_namespace && 'g++ -x c++' || 'gcc' }} + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Install brew dependencies + run: | + HOMEBREW_NO_AUTO_UPDATE=1 brew install readline + if: ${{ contains(matrix.os, 'macos') }} + + - name: Install APT dependencies + run: | + sudo apt install -y libreadline-dev + if: ${{ !contains(matrix.os, 'macos') }} + + - name: Build Executable + run: | + make -j3 ${MAKE_ARGS} abc + + - name: Test Executable + run: | + ./abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec" + + - name: Build Library + run: | + make -j3 ${MAKE_ARGS} libabc.a + + - name: Test Library + run: | + ${DEMO_GCC} ${DEMO_ARGS} -Wall -c src/demo.c -o demo.o + g++ -o demo demo.o libabc.a -lm -ldl -lreadline -lpthread + ./demo i10.aig + + - name: Stage Executable + run: | + mkdir staging + cp abc libabc.a staging/ + + - name: Upload pacakge artifact + uses: actions/upload-artifact@v1 + with: + name: package + path: staging/ diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 000000000..6312780d8 --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,48 @@ +on: [push] + +jobs: + + build-windows: + + runs-on: windows-latest + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Process project files to compile on Github Actions + run: | + sed -i 's#ABC_USE_PTHREADS\"#ABC_DONT_USE_PTHREADS\" /D \"_ALLOW_KEYWORD_MACROS=1\"#g' *.dsp + awk 'BEGIN { del=0; } /# Begin Group "uap"/ { del=1; } /# End Group/ { if( del > 0 ) {del=0; next;} } del==0 {print;} ' abclib.dsp > tmp.dsp + copy tmp.dsp abclib.dsp + del tmp.dsp + unix2dos *.dsp + + - name: Prepare MSVC + uses: bus1/cabuild/action/msdevshell@v1 + with: + architecture: x86 + + - name: Upgrade project files to latest Visual Studio, ignoring upgrade errors, and build + run: | + devenv abcspace.dsw /upgrade ; if (-not $? ) { cat UpgradeLog.htm } + msbuild abcspace.sln /m /nologo /p:Configuration=Release /p:PlatformTarget=x86 + + - name: Test Executable + run: | + _TEST\abc.exe -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec" + + - name: Stage Executable + run: | + mkdir staging + copy _TEST/abc.exe staging/ + copy UpgradeLog.htm staging/ + + - name: Upload pacakge artifact + uses: actions/upload-artifact@v1 + with: + name: package + path: staging/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b9add8c43..000000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: cpp - -matrix: - include: - - - os: linux - addons: - apt: - packages: - - libreadline-dev - - - os: linux - addons: - apt: - packages: - - libreadline-dev - env: - MAKE_ARGS: ABC_USE_NAMESPACE=xxx - DEMO_ARGS: -DABC_NAMESPACE=xxx - - - os: osx - osx_image: xcode10 - addons: - homebrew: - packages: - - readline - -script: - - - make ${MAKE_ARGS} -j2 abc - - ./abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec" - - - make ${MAKE_ARGS} libabc.a - - g++ ${DEMO_ARGS} -Wall -c src/demo.c -o demo.o - - g++ -o demo demo.o libabc.a -lm -ldl -lreadline -lpthread - - ./demo i10.aig diff --git a/Makefile b/Makefile index bdea392ac..3976cf7b1 100644 --- a/Makefile +++ b/Makefile @@ -61,9 +61,9 @@ ifneq ($(findstring arm,$(shell uname -m)),) CFLAGS += -DABC_MEMALIGN=4 endif -# compile ABC using the C++ comipler and put everything in the namespace $(ABC_NAMESPACE) +# compile ABC using the C++ compiler and put everything in the namespace $(ABC_NAMESPACE) ifdef ABC_USE_NAMESPACE - CFLAGS += -DABC_NAMESPACE=$(ABC_USE_NAMESPACE) -fpermissive + CFLAGS += -DABC_NAMESPACE=$(ABC_USE_NAMESPACE) -fpermissive -x c++ CC := $(CXX) $(info $(MSG_PREFIX)Compiling in namespace $(ABC_NAMESPACE)) endif diff --git a/README.md b/README.md index be6178770..55b9de306 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Build Status](https://travis-ci.org/berkeley-abc/abc.svg?branch=master)](https://travis-ci.org/berkeley-abc/abc) -[![Build status](https://ci.appveyor.com/api/projects/status/7q8gopidgvyos00d?svg=true)](https://ci.appveyor.com/project/berkeley-abc/abc) +[![.github/workflows/build-posix.yml](https://github.com/sterin/abc/actions/workflows/build-posix.yml/badge.svg)](https://github.com/sterin/abc/actions/workflows/build-posix.yml) +[![.github/workflows/build-windows.yml](https://github.com/sterin/abc/actions/workflows/build-windows.yml/badge.svg)](https://github.com/sterin/abc/actions/workflows/build-windows.yml) # ABC: System for Sequential Logic Synthesis and Formal Verification diff --git a/src/base/acb/acbTest.c b/src/base/acb/acbTest.c index 1faea72ab..6290b88ea 100644 --- a/src/base/acb/acbTest.c +++ b/src/base/acb/acbTest.c @@ -466,7 +466,7 @@ Gia_Man_t * Acb_NtkGiaDeriveMiter( Gia_Man_t * pOne, Gia_Man_t * pTwo, int Type ***********************************************************************/ void Acb_OutputFile( char * pFileName, Acb_Ntk_t * pNtkF, int * pModel ) { - char * pFileName0 = pFileName? pFileName : "output"; + const char * pFileName0 = pFileName? pFileName : "output"; FILE * pFile = fopen( pFileName0, "wb" ); if ( pFile == NULL ) { diff --git a/src/proof/cec/cecSolveG.c b/src/proof/cec/cecSolveG.c index 0bb68a7f0..c4b01b509 100644 --- a/src/proof/cec/cecSolveG.c +++ b/src/proof/cec/cecSolveG.c @@ -445,7 +445,7 @@ void CecG_ManSatSolverRecycle( Cec_ManSat_t * p ) // memset( p->pSatVars, 0, sizeof(int) * Gia_ManObjNumMax(p->pAigTotal) ); sat_solver_stop( p->pSat ); } - p->pSat = sat_solver_start(); + p->pSat = (struct sat_solver_t*)sat_solver_start(); assert( 0 <= p->pPars->SolverType && p->pPars->SolverType <= 2 ); sat_solver_set_jftr( p->pSat, p->pPars->SolverType ); //sat_solver_setnvars( p->pSat, 1000 ); // minisat only diff --git a/src/sat/msat/msatClause.c b/src/sat/msat/msatClause.c index 6b1b9e988..3d1fa2fc8 100644 --- a/src/sat/msat/msatClause.c +++ b/src/sat/msat/msatClause.c @@ -522,7 +522,7 @@ void Msat_ClausePrintSymbols( Msat_Clause_t * pC ) // if ( pC->fLearned ) // printf( "Act = %.4f ", Msat_ClauseReadActivity(pC) ); for ( i = 0; i < (int)pC->nSize; i++ ) - printf(" "L_LIT, L_lit(pC->pData[i])); + printf(" " L_LIT, L_lit(pC->pData[i])); } printf( "\n" ); } diff --git a/src/sat/msat/msatSolverSearch.c b/src/sat/msat/msatSolverSearch.c index b3190e39c..2eda5038d 100644 --- a/src/sat/msat/msatSolverSearch.c +++ b/src/sat/msat/msatSolverSearch.c @@ -52,7 +52,7 @@ int Msat_SolverAssume( Msat_Solver_t * p, Msat_Lit_t Lit ) { assert( Msat_QueueReadSize(p->pQueue) == 0 ); if ( p->fVerbose ) - printf(L_IND"assume("L_LIT")\n", L_ind, L_lit(Lit)); + printf(L_IND "assume(" L_LIT ")\n", L_ind, L_lit(Lit)); Msat_IntVecPush( p->vTrailLim, Msat_IntVecReadSize(p->vTrail) ); // assert( Msat_IntVecReadSize(p->vTrailLim) <= Msat_IntVecReadSize(p->vTrail) + 1 ); // assert( Msat_IntVecReadSize( p->vTrailLim ) < p->nVars ); @@ -83,7 +83,7 @@ void Msat_SolverUndoOne( Msat_Solver_t * p ) Msat_OrderVarUnassigned( p->pOrder, Var ); if ( p->fVerbose ) - printf(L_IND"unbind("L_LIT")\n", L_ind, L_lit(Lit)); + printf(L_IND "unbind(" L_LIT")\n", L_ind, L_lit(Lit)); } /**Function************************************************************* @@ -107,7 +107,7 @@ void Msat_SolverCancel( Msat_Solver_t * p ) { Msat_Lit_t Lit; Lit = Msat_IntVecReadEntry( p->vTrail, Msat_IntVecReadEntryLast(p->vTrailLim) ); - printf(L_IND"cancel("L_LIT")\n", L_ind, L_lit(Lit)); + printf(L_IND "cancel(" L_LIT ")\n", L_ind, L_lit(Lit)); } } for ( c = Msat_IntVecReadSize(p->vTrail) - Msat_IntVecPop( p->vTrailLim ); c != 0; c-- ) @@ -188,7 +188,7 @@ int Msat_SolverEnqueue( Msat_Solver_t * p, Msat_Lit_t Lit, Msat_Clause_t * pC ) if ( p->fVerbose ) { // printf(L_IND"bind("L_LIT")\n", L_ind, L_lit(Lit)); - printf(L_IND"bind("L_LIT") ", L_ind, L_lit(Lit)); + printf(L_IND "bind(" L_LIT ") ", L_ind, L_lit(Lit)); Msat_ClausePrintSymbols( pC ); } p->pAssigns[Var] = Lit; @@ -513,7 +513,7 @@ void Msat_SolverAnalyze( Msat_Solver_t * p, Msat_Clause_t * pC, Msat_IntVec_t * nReasonSize = Msat_IntVecReadSize( vLits_out ); pReasonArray = Msat_IntVecReadArray( vLits_out ); for ( j = 0; j < nReasonSize; j++ ) - printf(" "L_LIT, L_lit(pReasonArray[j])); + printf(" " L_LIT, L_lit(pReasonArray[j])); printf(" } at level %d\n", *pLevel_out); } } From 5fc7e6aac5b5ae42feac13ea347c47281e350516 Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Sat, 22 Jan 2022 22:06:11 +0200 Subject: [PATCH 19/74] Build CMake on GitHub Actions --- .../build-posix.yml | 0 .../build-windows.yml | 0 .github/workflows/build-posix-cmake.yml | 62 +++++++++++++++++++ 3 files changed, 62 insertions(+) rename .github/{workflows => disabled-workflows}/build-posix.yml (100%) rename .github/{workflows => disabled-workflows}/build-windows.yml (100%) create mode 100644 .github/workflows/build-posix-cmake.yml diff --git a/.github/workflows/build-posix.yml b/.github/disabled-workflows/build-posix.yml similarity index 100% rename from .github/workflows/build-posix.yml rename to .github/disabled-workflows/build-posix.yml diff --git a/.github/workflows/build-windows.yml b/.github/disabled-workflows/build-windows.yml similarity index 100% rename from .github/workflows/build-windows.yml rename to .github/disabled-workflows/build-windows.yml diff --git a/.github/workflows/build-posix-cmake.yml b/.github/workflows/build-posix-cmake.yml new file mode 100644 index 000000000..86a4d0f9d --- /dev/null +++ b/.github/workflows/build-posix-cmake.yml @@ -0,0 +1,62 @@ +on: [push] + +jobs: + + build-posix: + strategy: + matrix: + os: [macos-latest, ubuntu-latest] + use_namespace: [false, true] + + runs-on: ${{ matrix.os }} + + env: + MAKE_ARGS: ${{ matrix.use_namespace && '-DABC_USE_NAMESPACE=ON' || '' }} + DEMO_ARGS: ${{ matrix.use_namespace && '-DABC_NAMESPACE=xxx' || '' }} + DEMO_GCC: ${{ matrix.use_namespace && 'g++ -x c++' || 'gcc' }} + + steps: + + - name: Git Checkout + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Install brew dependencies + run: | + HOMEBREW_NO_AUTO_UPDATE=1 brew install readline + if: ${{ contains(matrix.os, 'macos') }} + + - name: Install APT dependencies + run: | + sudo apt install -y libreadline-dev + if: ${{ !contains(matrix.os, 'macos') }} + + - name: Configure CMake + run: | + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -B build + + - name: Build CMake + run: | + cmake --build build + + - name: Test Executable + run: | + ./build/abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec" + + - name: Test Library + run: | + ${DEMO_GCC} ${DEMO_ARGS} -Wall -c src/demo.c -o demo.o + g++ -o demo demo.o build/libabc.a -lm -ldl -lreadline -lpthread + ./demo i10.aig + + - name: Stage Executable + run: | + mkdir staging + cp abc libabc.a staging/ + + - name: Upload pacakge artifact + uses: actions/upload-artifact@v1 + with: + name: package + path: staging/ From fd975af1595dbf8f8a703591dac7b5f0059925db Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Sat, 22 Jan 2022 22:07:33 +0200 Subject: [PATCH 20/74] Build CMake on GitHub Actions 2 --- .github/workflows/build-posix-cmake.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-posix-cmake.yml b/.github/workflows/build-posix-cmake.yml index 86a4d0f9d..68d325b2c 100644 --- a/.github/workflows/build-posix-cmake.yml +++ b/.github/workflows/build-posix-cmake.yml @@ -24,12 +24,12 @@ jobs: - name: Install brew dependencies run: | - HOMEBREW_NO_AUTO_UPDATE=1 brew install readline + HOMEBREW_NO_AUTO_UPDATE=1 brew install readline ninja if: ${{ contains(matrix.os, 'macos') }} - name: Install APT dependencies run: | - sudo apt install -y libreadline-dev + sudo apt install -y libreadline-dev ninja-build if: ${{ !contains(matrix.os, 'macos') }} - name: Configure CMake From 2ccb0f783495a65cc597865ba24556cc64b8eaa1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 22 Jan 2022 13:26:06 -0800 Subject: [PATCH 21/74] Suggested bug fix. --- src/aig/gia/giaPat2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index fef4cf5a8..dff2c59d2 100644 --- a/src/aig/gia/giaPat2.c +++ b/src/aig/gia/giaPat2.c @@ -346,7 +346,7 @@ void Min_LitMinimize( Min_Man_t * p, int iLit, Vec_Int_t * vLits ) Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); else if ( Val0 == 4 && Val1 != 4 ) Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); - else if ( Val1 == 4 && Val1 != 4 ) + else if ( Val1 == 4 && Val0 != 4 ) Min_ObjMarkValL( p, Abc_Lit2Var(iLit1) ); else if ( Abc_Random(0) & 1 ) Min_ObjMarkValL( p, Abc_Lit2Var(iLit0) ); From 0a536417f6be75fcf26720767a61bd1f57a685b5 Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Sun, 23 Jan 2022 00:16:10 +0100 Subject: [PATCH 22/74] Build CMake on GitHub Actions Also, resolve CMake build problems on macOS: Pass CMAKE_OSX_SYSROOT as an environment variable SDKROOT when buildind the arch_flags executable. --- .github/workflows/build-posix-cmake.yml | 6 +++--- .github/{disabled-workflows => workflows}/build-posix.yml | 0 .github/{disabled-workflows => workflows}/build-windows.yml | 0 CMakeLists.txt | 5 +++++ README.md | 5 +++-- 5 files changed, 11 insertions(+), 5 deletions(-) rename .github/{disabled-workflows => workflows}/build-posix.yml (100%) rename .github/{disabled-workflows => workflows}/build-windows.yml (100%) diff --git a/.github/workflows/build-posix-cmake.yml b/.github/workflows/build-posix-cmake.yml index 68d325b2c..ea31fe0bc 100644 --- a/.github/workflows/build-posix-cmake.yml +++ b/.github/workflows/build-posix-cmake.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} env: - MAKE_ARGS: ${{ matrix.use_namespace && '-DABC_USE_NAMESPACE=ON' || '' }} + CMAKE_ARGS: ${{ matrix.use_namespace && '-DABC_USE_NAMESPACE=xxx' || '' }} DEMO_ARGS: ${{ matrix.use_namespace && '-DABC_NAMESPACE=xxx' || '' }} DEMO_GCC: ${{ matrix.use_namespace && 'g++ -x c++' || 'gcc' }} @@ -34,7 +34,7 @@ jobs: - name: Configure CMake run: | - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -B build + cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ${CMAKE_ARGS} -B build - name: Build CMake run: | @@ -53,7 +53,7 @@ jobs: - name: Stage Executable run: | mkdir staging - cp abc libabc.a staging/ + cp build/abc build/libabc.a staging/ - name: Upload pacakge artifact uses: actions/upload-artifact@v1 diff --git a/.github/disabled-workflows/build-posix.yml b/.github/workflows/build-posix.yml similarity index 100% rename from .github/disabled-workflows/build-posix.yml rename to .github/workflows/build-posix.yml diff --git a/.github/disabled-workflows/build-windows.yml b/.github/workflows/build-windows.yml similarity index 100% rename from .github/disabled-workflows/build-windows.yml rename to .github/workflows/build-windows.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cf6f19af..cee9bc72f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,9 +47,14 @@ if(ABC_USE_NAMESPACE) set(ABC_USE_NAMESPACE_FLAGS "ABC_USE_NAMESPACE=${ABC_USE_NAMESPACE}") endif() +if( APPLE ) + set(make_env ${CMAKE_COMMAND} -E env SDKROOT=${CMAKE_OSX_SYSROOT}) +endif() + # run make to extract compiler options, linker options and list of source files execute_process( COMMAND + ${make_env} make ${ABC_READLINE_FLAGS} ${ABC_USE_NAMESPACE_FLAGS} diff --git a/README.md b/README.md index 55b9de306..358f5ce9a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -[![.github/workflows/build-posix.yml](https://github.com/sterin/abc/actions/workflows/build-posix.yml/badge.svg)](https://github.com/sterin/abc/actions/workflows/build-posix.yml) -[![.github/workflows/build-windows.yml](https://github.com/sterin/abc/actions/workflows/build-windows.yml/badge.svg)](https://github.com/sterin/abc/actions/workflows/build-windows.yml) +[![.github/workflows/build-posix.yml](https://github.com/berkeley-abc/abc/actions/workflows/build-posix.yml/badge.svg)](https://github.com/berkeley-abc/abc/actions/workflows/build-posix.yml) +[![.github/workflows/build-windows.yml](https://github.com/berkeley-abc/abc/actions/workflows/build-windows.yml/badge.svg)](https://github.com/berkeley-abc/abc/actions/workflows/build-windows.yml) +[![.github/workflows/build-posix-cmake.yml](https://github.com/berkeley-abc/abc/actions/workflows/build-posix-cmake.yml/badge.svg)](https://github.com/berkeley-abc/abc/actions/workflows/build-posix-cmake.yml) # ABC: System for Sequential Logic Synthesis and Formal Verification From 6097ac1d1aa67732a98caab517a510731fb2f0b1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Feb 2022 17:21:30 -0800 Subject: [PATCH 23/74] Adding option to dump CNF after preprocessing in &glucose. --- src/sat/bsat2/Solver.cpp | 2 +- src/sat/glucose/AbcGlucose.cpp | 11 ++++++++++- src/sat/glucose/AbcGlucose.h | 2 +- src/sat/glucose/AbcGlucoseCmd.cpp | 11 ++++++++--- src/sat/glucose/Glucose.cpp | 2 +- src/sat/glucose2/Glucose2.cpp | 2 +- 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/sat/bsat2/Solver.cpp b/src/sat/bsat2/Solver.cpp index 451beed87..0f8b415a9 100644 --- a/src/sat/bsat2/Solver.cpp +++ b/src/sat/bsat2/Solver.cpp @@ -820,7 +820,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec& map, Var& max) void Solver::toDimacs(const char *file, const vec& assumps) { - FILE* f = fopen(file, "wr"); + FILE* f = fopen(file, "wb"); if (f == NULL) fprintf(stderr, "could not open file %s\n", file), exit(1); toDimacs(f, assumps); diff --git a/src/sat/glucose/AbcGlucose.cpp b/src/sat/glucose/AbcGlucose.cpp index ad595ab96..9c23e0d00 100644 --- a/src/sat/glucose/AbcGlucose.cpp +++ b/src/sat/glucose/AbcGlucose.cpp @@ -818,7 +818,7 @@ void Glucose_ReadDimacs( char * pFileName, SimpSolver& s ) SeeAlso [] ***********************************************************************/ -void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars ) +void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars, int fDumpCnf ) { abctime clk = Abc_Clock(); @@ -844,6 +844,15 @@ void Glucose_SolveCnf( char * pFileName, Glucose_Pars * pPars ) S.eliminate(true); printf( "c Simplication removed %d variables and %d clauses. ", S.eliminated_vars, S.eliminated_clauses ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + + if ( fDumpCnf ) + { + char * pFileCnf = Extra_FileNameGenericAppend( pFileName, "_out.cnf" ); + S.toDimacs(pFileCnf); + printf( "Finished dumping CNF after preprocessing into file \"%s\".\n", pFileCnf ); + printf( "SAT solving is not performed.\n" ); + return; + } } vec dummy; diff --git a/src/sat/glucose/AbcGlucose.h b/src/sat/glucose/AbcGlucose.h index 89a3652fe..c73f99188 100644 --- a/src/sat/glucose/AbcGlucose.h +++ b/src/sat/glucose/AbcGlucose.h @@ -105,7 +105,7 @@ extern void bmcg_sat_solver_start_new_round( bmcg_sat_solver * s ); extern void bmcg_sat_solver_mark_cone( bmcg_sat_solver * s, int var ); -extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars ); +extern void Glucose_SolveCnf( char * pFilename, Glucose_Pars * pPars, int fDumpCnf ); extern int Glucose_SolveAig( Gia_Man_t * p, Glucose_Pars * pPars ); ABC_NAMESPACE_HEADER_END diff --git a/src/sat/glucose/AbcGlucoseCmd.cpp b/src/sat/glucose/AbcGlucoseCmd.cpp index 2e819e497..bb957547c 100644 --- a/src/sat/glucose/AbcGlucoseCmd.cpp +++ b/src/sat/glucose/AbcGlucoseCmd.cpp @@ -81,10 +81,11 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv ) int pre = 1; int verb = 0; int nConfls = 0; + int fDumpCnf = 0; Glucose_Pars pPars; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Cpvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Cpdvh" ) ) != EOF ) { switch ( c ) { @@ -102,6 +103,9 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'p': pre ^= 1; break; + case 'd': + fDumpCnf ^= 1; + break; case 'v': verb ^= 1; break; @@ -116,7 +120,7 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( argc == globalUtilOptind + 1 ) { - Glucose_SolveCnf( argv[globalUtilOptind], &pPars ); + Glucose_SolveCnf( argv[globalUtilOptind], &pPars, fDumpCnf ); return 0; } @@ -132,10 +136,11 @@ int Abc_CommandGlucose( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &glucose [-C num] [-pvh] \n" ); + Abc_Print( -2, "usage: &glucose [-C num] [-pdvh] \n" ); Abc_Print( -2, "\t run Glucose 3.0 by Gilles Audemard and Laurent Simon\n" ); Abc_Print( -2, "\t-C num : conflict limit [default = %d]\n", nConfls ); Abc_Print( -2, "\t-p : enable preprocessing [default = %d]\n",pre); + Abc_Print( -2, "\t-d : enable dumping CNF after proprocessing [default = %d]\n",fDumpCnf); Abc_Print( -2, "\t-v : verbosity [default = %d]\n",verb); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t : (optional) CNF file to solve\n"); diff --git a/src/sat/glucose/Glucose.cpp b/src/sat/glucose/Glucose.cpp index c975c6ca1..cfb388de6 100644 --- a/src/sat/glucose/Glucose.cpp +++ b/src/sat/glucose/Glucose.cpp @@ -1330,7 +1330,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec& map, Var& max) void Solver::toDimacs(const char *file, const vec& assumps) { - FILE* f = fopen(file, "wr"); + FILE* f = fopen(file, "wb"); if (f == NULL) fprintf(stderr, "could not open file %s\n", file), exit(1); toDimacs(f, assumps); diff --git a/src/sat/glucose2/Glucose2.cpp b/src/sat/glucose2/Glucose2.cpp index 7a8b265be..4b4c28e78 100644 --- a/src/sat/glucose2/Glucose2.cpp +++ b/src/sat/glucose2/Glucose2.cpp @@ -1535,7 +1535,7 @@ void Solver::toDimacs(FILE* f, Clause& c, vec& map, Var& max) void Solver::toDimacs(const char *file, const vec& assumps) { - FILE* f = fopen(file, "wr"); + FILE* f = fopen(file, "wb"); if (f == NULL) fprintf(stderr, "could not open file %s\n", file), exit(1); toDimacs(f, assumps); From a6f8625d64e26087b24f9d86b7e7181a05884fda Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Feb 2022 21:37:31 -0800 Subject: [PATCH 24/74] Experiments with word-level data structures. --- src/aig/gia/giaMan.c | 2 +- src/base/wlc/wlcCom.c | 20 +- src/base/wln/wlnRead.c | 420 ++++++++++++++++++++++++++++++++++++++--- src/base/wln/wlnRtl.c | 31 ++- 4 files changed, 440 insertions(+), 33 deletions(-) diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index a40673a7a..ec733b852 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -539,7 +539,7 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars ) Abc_Print( 1, " %s =%8d", p->pMuxes? "nod" : "and", Gia_ManAndNum(p) ); SetConsoleTextAttribute( hConsole, 13 ); // magenta Abc_Print( 1, " lev =%5d", Gia_ManLevelNum(p) ); - Abc_Print( 1, " (%.2f)", Gia_ManLevelAve(p) ); + Abc_Print( 1, " (%7.2f)", Gia_ManLevelAve(p) ); SetConsoleTextAttribute( hConsole, 7 ); // normal } #else diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index d8b8247a4..2ea17169b 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -2130,18 +2130,22 @@ int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Rtl_LibOrderWires( Rtl_Lib_t * pLib ); extern void Rtl_LibOrderCells( Rtl_Lib_t * pLib ); extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); + extern void Rtl_LibBlast2( Rtl_Lib_t * pLib ); extern void Rtl_LibReorderModules( Rtl_Lib_t * pLib ); extern void Rtl_LibSolve( Rtl_Lib_t * pLib ); extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); Gia_Man_t * pGia = NULL; Rtl_Lib_t * pLib = Wlc_AbcGetRtl(pAbc); - int c, fPrepro = 0, fVerbose = 0; + int c, fOldBlast = 0, fPrepro = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "pvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF ) { switch ( c ) { + case 'o': + fOldBlast ^= 1; + break; case 'p': fPrepro ^= 1; break; @@ -2157,9 +2161,14 @@ int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) Rtl_LibPrintStats( pLib ); //Rtl_LibPrint( NULL, pLib ); Rtl_LibOrderWires( pLib ); - Rtl_LibOrderCells( pLib ); - Rtl_LibBlast( pLib ); + if ( fOldBlast ) + { + Rtl_LibOrderCells( pLib ); + Rtl_LibBlast( pLib ); + } + else + Rtl_LibBlast2( pLib ); //Rtl_LibReorderModules( pLib ); //Rtl_LibPrintStats( pLib ); @@ -2172,8 +2181,9 @@ int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManStopP( &pGia ); return 0; usage: - Abc_Print( -2, "usage: %%solve [-pvh]\n" ); + Abc_Print( -2, "usage: %%solve [-opvh]\n" ); Abc_Print( -2, "\t experiments with word-level networks\n" ); + Abc_Print( -2, "\t-o : toggle using old bit-blasting procedure [default = %s]\n", fOldBlast? "yes": "no" ); Abc_Print( -2, "\t-p : toggle preprocessing for verification [default = %s]\n", fPrepro? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 71b1b98c6..b58c25160 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -27,12 +27,13 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -#define MAX_LINE 10000 +#define MAX_LINE 1000000 -#define MAX_MAP 32 -#define CELL_NUM 8 -#define WIRE_NUM 5 -#define TEMP_NUM 5 +#define MAX_MAP 32 +#define CELL_NUM 8 +#define WIRE_NUM 5 +#define TEMP_NUM 5 +#define CONST_SHIFT 99 //typedef struct Rtl_Lib_t_ Rtl_Lib_t; struct Rtl_Lib_t_ @@ -58,14 +59,16 @@ struct Rtl_Ntk_t_ int nInputs; // word-level inputs int nOutputs; // word-level outputs Vec_Int_t vWires; // wires (name{upto,signed,in,out}+width+offset+number) - Vec_Int_t vCells; // instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[6]mark+(attr+params+conns)) + Vec_Int_t vCells; // instances ([0]type+[1]name+[2]mod+[3]ins+[4]nattr+[5]nparams+[6]nconns+[7]mark+(attr+params+conns)) Vec_Int_t vConns; // connection pairs Vec_Int_t vStore; // storage for cells Vec_Int_t vAttrs; // attributes Rtl_Lib_t * pLib; // parent Vec_Int_t vOrder; // topological order Vec_Int_t vLits; // bit-level view + Vec_Int_t vDrivers; // bit-level view Vec_Int_t vBitTemp; // storage for bits + Vec_Int_t vBitTemp2; // storage for bits Gia_Man_t * pGia; // derived by bit-blasting int Slice0; // first slice int Slice1; // last slice @@ -187,7 +190,9 @@ void Rtl_NtkFree( Rtl_Ntk_t * p ) ABC_FREE( p->vAttrs.pArray ); ABC_FREE( p->vOrder.pArray ); ABC_FREE( p->vLits.pArray ); + ABC_FREE( p->vDrivers.pArray ); ABC_FREE( p->vBitTemp.pArray ); + ABC_FREE( p->vBitTemp2.pArray ); ABC_FREE( p ); } void Rtl_NtkCountPio( Rtl_Ntk_t * p, int Counts[4] ) @@ -229,8 +234,8 @@ void Rtl_NtkPrintStats( Rtl_Ntk_t * p, int nNameSymbs ) { int Counts[4] = {0}; Rtl_NtkCountPio( p, Counts ); printf( "%*s : ", nNameSymbs, Rtl_NtkName(p) ); - printf( "PI = %3d (%3d) ", Counts[0], Counts[1] ); - printf( "PO = %3d (%3d) ", Counts[2], Counts[3] ); + printf( "PI = %5d (%5d) ", Counts[0], Counts[1] ); + printf( "PO = %5d (%5d) ", Counts[2], Counts[3] ); printf( "Wire = %6d ", Rtl_NtkWireNum(p) ); printf( "Cell = %6d ", Rtl_NtkCellNum(p) ); printf( "Con = %6d", Rtl_NtkConNum(p) ); @@ -897,22 +902,23 @@ void Rtl_TokenRespace( char * p ) Vec_Int_t * Rtl_NtkReadFile( char * pFileName, Abc_Nam_t * p ) { Vec_Int_t * vTokens; - char * pTemp, Buffer[MAX_LINE]; + char * pTemp, * pBuffer; FILE * pFile = fopen( pFileName, "rb" ); if ( pFile == NULL ) { printf( "Cannot open file \"%s\" for reading.\n", pFileName ); return NULL; } + pBuffer = ABC_ALLOC( char, MAX_LINE ); Abc_NamStrFindOrAdd( p, "module", NULL ); assert( Abc_NamObjNumMax(p) == 2 ); vTokens = Vec_IntAlloc( 1000 ); - while ( fgets( Buffer, MAX_LINE, pFile ) != NULL ) + while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL ) { - if ( Buffer[0] == '#' ) + if ( pBuffer[0] == '#' ) continue; - Rtl_TokenUnspace( Buffer ); - pTemp = strtok( Buffer, " \t\r\n" ); + Rtl_TokenUnspace( pBuffer ); + pTemp = strtok( pBuffer, " \t\r\n" ); if ( pTemp == NULL ) continue; while ( pTemp ) @@ -923,6 +929,7 @@ Vec_Int_t * Rtl_NtkReadFile( char * pFileName, Abc_Nam_t * p ) } Vec_IntPush( vTokens, -1 ); } + ABC_FREE( pBuffer ); fclose( pFile ); return vTokens; } @@ -1395,6 +1402,117 @@ Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern int Rtl_NtkMapSignalRange( Rtl_Ntk_t * p, int Sig, int iCell, int iBit ); + +int Rtl_NtkMapWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int iCell, int iBit ) +{ + //char * pName = Rtl_NtkStr( p, NameId ); + int Wire = Rtl_WireMapNameToId( p, NameId ); + int First = Rtl_WireBitStart( p, Wire ); + int Width = Rtl_WireWidth( p, Wire ), i, k = 0; + Left = Left == -1 ? Width-1 : Left; + Right = Right == -1 ? 0 : Right; + assert ( Right >= 0 && Right <= Left ); + for ( i = Right; i <= Left; i++ ) + { + assert( Vec_IntEntry(&p->vDrivers, 2*(First+i)) == -4 ); + Vec_IntWriteEntry(&p->vDrivers, 2*(First+i)+0, iCell ); + Vec_IntWriteEntry(&p->vDrivers, 2*(First+i)+1, iBit + (i - Right) ); + } + return Left - Right + 1; +} +int Rtl_NtkMapSliceRange( Rtl_Ntk_t * p, int * pSlice, int iCell, int iBit ) +{ + return Rtl_NtkMapWireRange( p, pSlice[0], pSlice[1], pSlice[2], iCell, iBit ); +} +int Rtl_NtkMapConcatRange( Rtl_Ntk_t * p, int * pConcat, int iCell, int iBit ) +{ + int i, k = 0; + for ( i = 1; i <= pConcat[0]; i++ ) + k += Rtl_NtkMapSignalRange( p, pConcat[i], iCell, iBit+k ); + return k; +} +int Rtl_NtkMapSignalRange( Rtl_Ntk_t * p, int Sig, int iCell, int iBit ) +{ + int nBits = ABC_INFINITY; + if ( Rtl_SigIsNone(Sig) ) + nBits = Rtl_NtkMapWireRange( p, Sig >> 2, -1, -1, iCell, iBit ); + if ( Rtl_SigIsSlice(Sig) ) + nBits = Rtl_NtkMapSliceRange( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2), iCell, iBit ); + if ( Rtl_SigIsConcat(Sig) ) + nBits = Rtl_NtkMapConcatRange( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2), iCell, iBit ); + if ( Rtl_SigIsConst(Sig) ) + assert( 0 ); + return nBits; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +extern void Rtl_NtkCollectSignalInfo( Rtl_Ntk_t * p, int Sig ); + +void Rtl_NtkCollectWireInfo( Rtl_Ntk_t * p, int NameId, int Left, int Right ) +{ + int Wire = Rtl_WireMapNameToId( p, NameId ); + int First = Rtl_WireBitStart( p, Wire ); + int Width = Rtl_WireWidth( p, Wire ), i; + Left = Left == -1 ? Width-1 : Left; + Right = Right == -1 ? 0 : Right; + assert ( Right >= 0 && Right <= Left ); + for ( i = Right; i <= Left; i++ ) + Vec_IntPush( &p->vBitTemp, First+i ); +} +void Rtl_NtkCollectConstInfo( Rtl_Ntk_t * p, int * pConst ) +{ + int i, nLimit = pConst[0]; + if ( nLimit == -1 ) + nLimit = 32; + for ( i = 0; i < nLimit; i++ ) + Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i)-CONST_SHIFT ); +} +void Rtl_NtkCollectSliceInfo( Rtl_Ntk_t * p, int * pSlice ) +{ + Rtl_NtkCollectWireInfo( p, pSlice[0], pSlice[1], pSlice[2] ); +} +void Rtl_NtkCollectConcatInfo( Rtl_Ntk_t * p, int * pConcat ) +{ + int i; + for ( i = pConcat[0]; i >= 1; i-- ) + Rtl_NtkCollectSignalInfo( p, pConcat[i] ); +} +void Rtl_NtkCollectSignalInfo( Rtl_Ntk_t * p, int Sig ) +{ + if ( Rtl_SigIsNone(Sig) ) + Rtl_NtkCollectWireInfo( p, Sig >> 2, -1, -1 ); + else if ( Rtl_SigIsConst(Sig) ) + Rtl_NtkCollectConstInfo( p, Vec_IntEntryP(&p->pLib->vConsts, Sig >> 2) ); + else if ( Rtl_SigIsSlice(Sig) ) + Rtl_NtkCollectSliceInfo( p, Vec_IntEntryP(&p->pLib->vSlices, Sig >> 2) ); + else if ( Rtl_SigIsConcat(Sig) ) + Rtl_NtkCollectConcatInfo( p, Vec_IntEntryP(&p->pLib->vConcats, Sig >> 2) ); + else assert( 0 ); +} + /**Function************************************************************* Synopsis [] @@ -1427,7 +1545,6 @@ void Rtl_NtkCollectConstRange( Rtl_Ntk_t * p, int * pConst ) int i, nLimit = pConst[0]; if ( nLimit == -1 ) nLimit = 32; - //assert( pConst[0] > 0 ); for ( i = 0; i < nLimit; i++ ) Vec_IntPush( &p->vBitTemp, Abc_InfoHasBit((unsigned *)pConst+1,i) ); } @@ -1609,6 +1726,20 @@ void Rtl_NtkBlastOperator( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) assert( nBits == Vec_IntSize(vRes) ); //printf( "Finished blasting cell %s (Value = %d).\n", Rtl_CellNameStr(p, pCell), Vec_IntEntry(vRes, 0) ); } +char * Rtl_ShortenName( char * pName, int nSize ) +{ + static char Buffer[1000]; + if ( (int)strlen(pName) <= nSize ) + return pName; + Buffer[0] = 0; + strcat( Buffer, pName ); + Buffer[nSize-4] = ' '; + Buffer[nSize-3] = '.'; + Buffer[nSize-2] = '.'; + Buffer[nSize-1] = '.'; + Buffer[nSize-0] = 0; + return Buffer; +} Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) { Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); @@ -1642,10 +1773,9 @@ Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); -sprintf( Buffer, "temp%d.aig", counter++ ); -//sprintf( Buffer, "temp%d.aig", counter ); +sprintf( Buffer, "old%02d.aig", counter++ ); Gia_AigerWrite( pNew, Buffer, 0, 0, 0 ); -printf( "Dumpted blasted AIG into file \"%s\" for module \"%s\".\n", Buffer, Rtl_NtkName(p) ); +printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) ); Gia_ManPrintStats( pNew, NULL ); return pNew; } @@ -1657,6 +1787,234 @@ void Rtl_LibBlast( Rtl_Lib_t * pLib ) p->pGia = Rtl_NtkBlast( p ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +// -4 unassigned +// -3 other bit +// -2 constant +// -1 primary input +// 0+ cell +int Rtl_NtkBlastCons( Rtl_Ntk_t * p ) +{ + int c, i, iBit0, iBit1, * pCon, * pDri0, * pDri1, nChanges = 0; + Rtl_NtkForEachCon( p, pCon, c ) + { + Vec_IntClear( &p->vBitTemp ); + Rtl_NtkCollectSignalInfo( p, pCon[1] ); + Vec_IntClearAppend( &p->vBitTemp2, &p->vBitTemp ); + + Vec_IntClear( &p->vBitTemp ); + Rtl_NtkCollectSignalInfo( p, pCon[0] ); + assert( Vec_IntSize(&p->vBitTemp2) == Vec_IntSize(&p->vBitTemp) ); + + Vec_IntForEachEntryTwo( &p->vBitTemp, &p->vBitTemp2, iBit0, iBit1, i ) + { + pDri0 = iBit0 >= 0 ? Vec_IntEntryP(&p->vDrivers, 2*iBit0) : NULL; + pDri1 = iBit1 >= 0 ? Vec_IntEntryP(&p->vDrivers, 2*iBit1) : NULL; + assert( iBit0 >= 0 || iBit1 >= 0 ); + if ( iBit0 < 0 ) + { + if ( pDri1[0] == -4 ) + { + assert( pDri1[1] == -4 ); + pDri1[0] = -2; + pDri1[1] = iBit0+CONST_SHIFT; + nChanges++; + } + continue; + } + if ( iBit1 < 0 ) + { + if ( pDri0[0] == -4 ) + { + assert( pDri0[1] == -4 ); + pDri0[0] = -2; + pDri0[1] = iBit1+CONST_SHIFT; + nChanges++; + } + continue; + } + if ( pDri0[0] == -4 && pDri1[0] != -4 ) + { + assert( pDri0[1] == -4 ); + pDri0[0] = -3; + pDri0[1] = iBit1; + nChanges++; + continue; + } + if ( pDri1[0] == -4 && pDri0[0] != -4 ) + { + assert( pDri1[1] == -4 ); + pDri1[0] = -3; + pDri1[1] = iBit0; + nChanges++; + continue; + } + } + } + //printf( "Changes %d\n", nChanges ); + return nChanges; +} +void Rtl_NtkBlastMap( Rtl_Ntk_t * p, int nBits ) +{ + int i, k, Par, Val, * pCell, iBit = 0, fChange = 1; + Vec_IntFill( &p->vDrivers, 2*nBits, -4 ); + for ( i = 0; i < p->nInputs; i++ ) + { + int First = Rtl_WireBitStart( p, i ); + int Width = Rtl_WireWidth( p, i ); + for ( k = 0; k < Width; k++ ) + { + assert( Vec_IntEntry(&p->vDrivers, 2*(First+k)) == -4 ); + Vec_IntWriteEntry(&p->vDrivers, 2*(First+k)+0, -1 ); + Vec_IntWriteEntry(&p->vDrivers, 2*(First+k)+1, iBit++ ); + } + } + Rtl_NtkForEachCell( p, pCell, i ) + { + int iBit = 0; + Rtl_CellForEachOutput( p, pCell, Par, Val, k ) + iBit += Rtl_NtkMapSignalRange( p, Val, i, iBit ); + } + for ( i = 0; i < 100; i++ ) + if ( !Rtl_NtkBlastCons(p) ) + break; + if ( i == 100 ) + printf( "Mapping connections did not succeed after %d iterations.\n", i ); +// else +// printf( "Mapping connections converged after %d iterations.\n", i ); +} +int Rtl_NtkCollectOrComputeBit( Rtl_Ntk_t * p, int iBit ) +{ + extern void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver ); + if ( Vec_IntEntry(&p->vLits, iBit) == -1 ) + { + int * pDriver = Vec_IntEntryP(&p->vDrivers, 2*iBit); + assert( pDriver[0] != -4 ); + Rtl_NtkBlast2_rec( p, iBit, pDriver ); + } + assert( Vec_IntEntry(&p->vLits, iBit) >= 0 ); + return Vec_IntEntry(&p->vLits, iBit); +} +int Rtl_NtkBlast2Spec( Rtl_Ntk_t * p, int * pCell, int iInput ) +{ + int i, Par, Val, pLits[3] = {-1, -1, -1}, iBit; + Rtl_CellForEachInput( p, pCell, Par, Val, i ) + { + Vec_Int_t * vTemp; + Vec_IntClear( &p->vBitTemp ); + Rtl_NtkCollectSignalInfo( p, Val ); + vTemp = Vec_IntDup( &p->vBitTemp ); + iBit = Vec_IntEntry( vTemp, i==2 ? 0 : iInput ); + if ( iBit >= 0 ) + pLits[i] = Rtl_NtkCollectOrComputeBit( p, iBit ); + else + pLits[i] = iBit+CONST_SHIFT; + assert( pLits[i] >= 0 ); + Vec_IntFree( vTemp ); + } + return Gia_ManHashMux(p->pGia, pLits[2], pLits[1], pLits[0]); +} +void Rtl_NtkBlastPrepareInputs( Rtl_Ntk_t * p, int * pCell ) +{ + int i, k, Par, Val, iBit; + Rtl_CellForEachInput( p, pCell, Par, Val, i ) + { + Vec_Int_t * vTemp; + Vec_IntClear( &p->vBitTemp ); + Rtl_NtkCollectSignalInfo( p, Val ); + vTemp = Vec_IntDup( &p->vBitTemp ); + Vec_IntForEachEntry( vTemp, iBit, k ) + if ( iBit >= 0 ) + Rtl_NtkCollectOrComputeBit( p, iBit ); + Vec_IntFree( vTemp ); + } +} +void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver ) +{ + assert( pDriver[0] != -1 ); + if ( pDriver[0] == -3 ) + { + int * pDriver1 = Vec_IntEntryP( &p->vDrivers, 2*pDriver[1] ); + if ( Vec_IntEntry(&p->vLits, pDriver[1]) == -1 ) + Rtl_NtkBlast2_rec( p, pDriver[1], pDriver1 ); + assert( Vec_IntEntry(&p->vLits, pDriver[1]) >= 0 ); + Vec_IntWriteEntry( &p->vLits, iBit, Vec_IntEntry(&p->vLits, pDriver[1]) ); + return; + } + if ( pDriver[0] == -2 ) + { + Vec_IntWriteEntry( &p->vLits, iBit, pDriver[1] ); + return; + } + else + { + int * pCell = Rtl_NtkCell(p, pDriver[0]); + assert( pDriver[0] >= 0 ); + if ( Rtl_CellModule(pCell) == ABC_OPER_SEL_NMUX ) // special case + { + int iLit = Rtl_NtkBlast2Spec( p, pCell, pDriver[1] ); + Vec_IntWriteEntry( &p->vLits, iBit, iLit ); + return; + } + Rtl_NtkBlastPrepareInputs( p, pCell ); + if ( Rtl_CellModule(pCell) >= ABC_INFINITY ) + Rtl_NtkBlastHierarchy( p->pGia, p, pCell ); + else if ( Rtl_CellModule(pCell) < ABC_OPER_LAST ) + Rtl_NtkBlastOperator( p->pGia, p, pCell ); + else + printf( "Cannot blast black box %s in module %s.\n", Rtl_NtkStr(p, Rtl_CellType(pCell)), Rtl_NtkName(p) ); + } +} +Gia_Man_t * Rtl_NtkBlast2( Rtl_Ntk_t * p ) +{ + Gia_Man_t * pTemp; + int i, b, nBits = Rtl_NtkRangeWires( p ); + char Buffer[100]; static int counter = 0; + Vec_IntFill( &p->vLits, nBits, -1 ); + Rtl_NtkMapWires( p, 0 ); + Rtl_NtkBlastMap( p, nBits ); + assert( p->pGia == NULL ); + p->pGia = Gia_ManStart( 1000 ); + Rtl_NtkBlastInputs( p->pGia, p ); + Gia_ManHashAlloc( p->pGia ); + for ( i = 0; i < p->nOutputs; i++ ) + { + int First = Rtl_WireBitStart( p, p->nInputs + i ); + int Width = Rtl_WireWidth( p, p->nInputs + i ); + for ( b = 0; b < Width; b++ ) + Rtl_NtkCollectOrComputeBit( p, First+b ); + } + Gia_ManHashStop( p->pGia ); + Rtl_NtkBlastOutputs( p->pGia, p ); + Rtl_NtkMapWires( p, 1 ); + p->pGia = Gia_ManCleanup( pTemp = p->pGia ); + Gia_ManStop( pTemp ); + +sprintf( Buffer, "new%02d.aig", counter++ ); +Gia_AigerWrite( p->pGia, Buffer, 0, 0, 0 ); +printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) ); +Gia_ManPrintStats( p->pGia, NULL ); + return p->pGia; +} +void Rtl_LibBlast2( Rtl_Lib_t * pLib ) +{ + Rtl_Ntk_t * p; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) + if ( p->pGia == NULL ) + p->pGia = Rtl_NtkBlast2( p ); +} + + /**Function************************************************************* Synopsis [] @@ -1705,21 +2063,31 @@ finish: Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) if ( p != p1 && p != p2 ) Gia_ManStopP( &p->pGia ); - Rtl_LibBlast( pLib ); + //Rtl_LibBlast( pLib ); + Rtl_LibBlast2( pLib ); } void Rtl_LibSolve( Rtl_Lib_t * pLib ) { + extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); abctime clk = Abc_Clock(); int Status; Rtl_Ntk_t * pTop = Rtl_LibTop( pLib ); - Gia_Man_t * pCopy = Gia_ManDup( pTop->pGia ); - Gia_ManInvertPos( pCopy ); - Gia_ManAppendCo( pCopy, 0 ); - Status = Cec_ManVerifySimple( pCopy ); - Gia_ManStop( pCopy ); - if ( Status == 1 ) - printf( "Verification problem solved! " ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pTop->pGia, 1000000, 0 ); + int RetValue = Gia_ManAndNum(pSwp) == 0; + Gia_ManStop( pSwp ); + if ( RetValue ) + printf( "Verification problem solved after SAT sweeping! " ); else - printf( "Verification problem is NOT solved! " ); + { + Gia_Man_t * pCopy = Gia_ManDup( pTop->pGia ); + Gia_ManInvertPos( pCopy ); + Gia_ManAppendCo( pCopy, 0 ); + Status = Cec_ManVerifySimple( pCopy ); + Gia_ManStop( pCopy ); + if ( Status == 1 ) + printf( "Verification problem solved after CEC! " ); + else + printf( "Verification problem is NOT solved! " ); + } Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index 89680bbdf..df53ebe0e 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -49,6 +49,34 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +#define MAX_LINE 1000000 + +void Rtl_NtkCleanFile( char * pFileName ) +{ + char * pBuffer, * pFileName2 = "_temp__.rtlil"; + FILE * pFile = fopen( pFileName, "rb" ); + FILE * pFile2; + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return; + } + pFile2 = fopen( pFileName2, "wb" ); + if ( pFile2 == NULL ) + { + fclose( pFile ); + printf( "Cannot open file \"%s\" for writing.\n", pFileName2 ); + return; + } + pBuffer = ABC_ALLOC( char, MAX_LINE ); + while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL ) + if ( !strstr(pBuffer, "attribute \\src") ) + fputs( pBuffer, pFile2 ); + ABC_FREE( pBuffer ); + fclose( pFile ); + fclose( pFile2 ); +} + char * Wln_GetYosysName() { char * pYosysName = NULL; @@ -105,7 +133,8 @@ Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCol printf( "Dumped the design into file \"%s\".\n", pFileTemp ); return NULL; } - //unlink( pFileTemp ); + Rtl_NtkCleanFile( pFileTemp ); + unlink( pFileTemp ); return pNtk; } Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ) From faa59472783121b7b8c7e4bd4c361a7f5aaf71ab Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Feb 2022 21:39:36 -0800 Subject: [PATCH 25/74] Compiler warnings. --- src/base/wln/wlnRead.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index b58c25160..62cb70c62 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -1420,7 +1420,7 @@ int Rtl_NtkMapWireRange( Rtl_Ntk_t * p, int NameId, int Left, int Right, int iCe //char * pName = Rtl_NtkStr( p, NameId ); int Wire = Rtl_WireMapNameToId( p, NameId ); int First = Rtl_WireBitStart( p, Wire ); - int Width = Rtl_WireWidth( p, Wire ), i, k = 0; + int Width = Rtl_WireWidth( p, Wire ), i; Left = Left == -1 ? Width-1 : Left; Right = Right == -1 ? 0 : Right; assert ( Right >= 0 && Right <= Left ); @@ -1866,7 +1866,7 @@ int Rtl_NtkBlastCons( Rtl_Ntk_t * p ) } void Rtl_NtkBlastMap( Rtl_Ntk_t * p, int nBits ) { - int i, k, Par, Val, * pCell, iBit = 0, fChange = 1; + int i, k, Par, Val, * pCell, iBit = 0; Vec_IntFill( &p->vDrivers, 2*nBits, -4 ); for ( i = 0; i < p->nInputs; i++ ) { From 6345832dba505bc60f78e5d165ca29d3842cbbd6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 3 Feb 2022 18:45:11 -0800 Subject: [PATCH 26/74] Improving truth table handling. --- src/base/abc/abc.h | 3 ++ src/base/abc/abcNtk.c | 46 +++++++++++++++++++++++++++++ src/base/abc/abcSop.c | 69 +++++++++++++++++++++++++++++++++++++++++-- src/base/io/io.c | 43 +++++++++++++++------------ src/base/wln/wlnRtl.c | 26 ++++++++++++++++ 5 files changed, 166 insertions(+), 21 deletions(-) diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index e7f6c0ad3..eea66f297 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -784,6 +784,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues ); extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode ); extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop ); +extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSops ); extern ABC_DLL void Abc_NtkDelete( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk ); extern ABC_DLL void Abc_NtkMakeComb( Abc_Ntk_t * pNtk, int fRemoveLatches ); @@ -920,6 +921,8 @@ extern ABC_DLL int Abc_SopIsExorType( char * pSop ); extern ABC_DLL int Abc_SopCheck( char * pSop, int nFanins ); extern ABC_DLL char * Abc_SopFromTruthBin( char * pTruth ); extern ABC_DLL char * Abc_SopFromTruthHex( char * pTruth ); +extern ABC_DLL Vec_Ptr_t * Abc_SopFromTruthsBin( char * pTruth ); +extern ABC_DLL Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth ); extern ABC_DLL char * Abc_SopEncoderPos( Mem_Flex_t * pMan, int iValue, int nValues ); extern ABC_DLL char * Abc_SopEncoderLog( Mem_Flex_t * pMan, int iBit, int nValues ); extern ABC_DLL char * Abc_SopDecoderPos( Mem_Flex_t * pMan, int nValues ); diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index f8e40b41b..633533442 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -1270,6 +1270,52 @@ Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop ) return pNtkNew; } +/**Function************************************************************* + + Synopsis [Creates the network composed of one node with the given SOP.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSop ) +{ + Abc_Ntk_t * pNtkNew; + Abc_Obj_t * pFanin, * pNode, * pNodePo; + Vec_Ptr_t * vNames; + int i, k, nVars; char Buffer[10]; + char * pSop = (char *)Vec_PtrEntry(vSop, 0); + // start the network + pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 ); + pNtkNew->pName = Extra_UtilStrsav("ex"); + // create PIs + Vec_PtrPush( pNtkNew->vObjs, NULL ); + nVars = Abc_SopGetVarNum( pSop ); + vNames = Abc_NodeGetFakeNames( nVars ); + for ( i = 0; i < nVars; i++ ) + Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), (char *)Vec_PtrEntry(vNames, i), NULL ); + Abc_NodeFreeNames( vNames ); + // create the node, add PIs as fanins, set the function + Vec_PtrForEachEntry( char *, vSop, pSop, i ) + { + pNode = Abc_NtkCreateNode( pNtkNew ); + Abc_NtkForEachPi( pNtkNew, pFanin, k ) + Abc_ObjAddFanin( pNode, pFanin ); + pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop ); + // create the only PO + pNodePo = Abc_NtkCreatePo(pNtkNew); + Abc_ObjAddFanin( pNodePo, pNode ); + sprintf( Buffer, "F%d", i ); + Abc_ObjAssignName( pNodePo, Buffer, NULL ); + } + if ( !Abc_NtkCheck( pNtkNew ) ) + fprintf( stdout, "Abc_NtkCreateWithNode(): Network check has failed.\n" ); + return pNtkNew; +} + /**Function************************************************************* Synopsis [Deletes the Ntk.] diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index b91214af1..a560a249f 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -907,6 +907,41 @@ int Abc_SopCheck( char * pSop, int nFanins ) return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_SopCheckReadTruth( Vec_Ptr_t * vRes, char * pToken, int fHex ) +{ + char * pBase; int nVars; + int Log2 = Abc_Base2Log( strlen(pToken) ); + if ( (1 << Log2) != (int)strlen(pToken) ) + { + printf( "The truth table length (%d) is not power-of-2.\n", strlen(pToken) ); + Vec_PtrFreeData( vRes ); + Vec_PtrShrink( vRes, 0 ); + return 0; + } + if ( Vec_PtrSize(vRes) == 0 ) + return 1; + pBase = (char *)Vec_PtrEntry( vRes, 0 ); + nVars = Abc_SopGetVarNum( pBase ); + if ( nVars != Log2+2*fHex ) + { + printf( "Truth table #1 has %d vars while truth table #%d has %d vars.\n", nVars, Vec_PtrSize(vRes)+1, Log2+2*fHex ); + Vec_PtrFreeData( vRes ); + Vec_PtrShrink( vRes, 0 ); + return 0; + } + return 1; +} /**Function************************************************************* @@ -964,8 +999,8 @@ char * Abc_SopFromTruthBin( char * pTruth ) { pCube = pSopCover + i * (nVars + 3); for ( b = 0; b < nVars; b++ ) - if ( Mint & (1 << (nVars-1-b)) ) -// if ( Mint & (1 << b) ) +// if ( Mint & (1 << (nVars-1-b)) ) + if ( Mint & (1 << b) ) pCube[b] = '1'; else pCube[b] = '0'; @@ -976,6 +1011,21 @@ char * Abc_SopFromTruthBin( char * pTruth ) Vec_IntFree( vMints ); return pSopCover; } +Vec_Ptr_t * Abc_SopFromTruthsBin( char * pTruth ) +{ + Vec_Ptr_t * vRes = Vec_PtrAlloc( 10 ); + char * pCopy = Abc_UtilStrsav(pTruth); + char * pToken = strtok( pCopy, " \r\n\t|" ); + while ( pToken ) + { + if ( !Abc_SopCheckReadTruth( vRes, pToken, 0 ) ) + break; + Vec_PtrPush( vRes, Abc_SopFromTruthBin(pToken) ); + pToken = strtok( NULL, " \r\n\t|" ); + } + ABC_FREE( pCopy ); + return vRes; +} /**Function************************************************************* @@ -1058,6 +1108,21 @@ char * Abc_SopFromTruthHex( char * pTruth ) Vec_IntFree( vMints ); return pSopCover; } +Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth ) +{ + Vec_Ptr_t * vRes = Vec_PtrAlloc( 10 ); + char * pCopy = Abc_UtilStrsav(pTruth); + char * pToken = strtok( pCopy, " \r\n\t|" ); + while ( pToken ) + { + if ( !Abc_SopCheckReadTruth( vRes, pToken, 1 ) ) + break; + Vec_PtrPush( vRes, Abc_SopFromTruthHex(pToken) ); + pToken = strtok( NULL, " \r\n\t|" ); + } + ABC_FREE( pCopy ); + return vRes; +} /**Function************************************************************* diff --git a/src/base/io/io.c b/src/base/io/io.c index 5cf74ef94..72fd25bfb 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1115,7 +1115,7 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk; char * pStr = NULL; - char * pSopCover; + Vec_Ptr_t * vSops; int fHex = 1; int fFile = 0; int c; @@ -1145,25 +1145,23 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) pStr = Extra_FileReadContents( argv[globalUtilOptind] ); else pStr = argv[globalUtilOptind]; - while ( pStr[ strlen(pStr) - 1 ] == '\n' || pStr[ strlen(pStr) - 1 ] == '\r' ) - pStr[ strlen(pStr) - 1 ] = '\0'; // convert truth table to SOP if ( fHex ) - pSopCover = Abc_SopFromTruthHex(pStr); + vSops = Abc_SopFromTruthsHex(pStr); else - pSopCover = Abc_SopFromTruthBin(pStr); + vSops = Abc_SopFromTruthsBin(pStr); if ( fFile ) ABC_FREE( pStr ); - if ( pSopCover == NULL || pSopCover[0] == 0 ) + if ( Vec_PtrSize(vSops) == 0 ) { - ABC_FREE( pSopCover ); + Vec_PtrFreeFree( vSops ); fprintf( pAbc->Err, "Reading truth table has failed.\n" ); return 1; } - pNtk = Abc_NtkCreateWithNode( pSopCover ); - ABC_FREE( pSopCover ); + pNtk = Abc_NtkCreateWithNodes( vSops ); + Vec_PtrFreeFree( vSops ); if ( pNtk == NULL ) { fprintf( pAbc->Err, "Deriving the network has failed.\n" ); @@ -1176,9 +1174,9 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: fprintf( pAbc->Err, "usage: read_truth [-xfh] \n" ); - fprintf( pAbc->Err, "\t creates network with node having given truth table\n" ); - fprintf( pAbc->Err, "\t-x : toggles between bin and hex representation [default = %s]\n", fHex? "hex":"bin" ); - fprintf( pAbc->Err, "\t-f : toggles reading truth table from file [default = %s]\n", fFile? "yes": "no" ); + fprintf( pAbc->Err, "\t creates network with node(s) having given truth table(s)\n" ); + fprintf( pAbc->Err, "\t-x : toggles between bin and hex notation [default = %s]\n", fHex? "hex":"bin" ); + fprintf( pAbc->Err, "\t-f : toggles reading truth table(s) from file [default = %s]\n", fFile? "yes": "no" ); fprintf( pAbc->Err, "\t-h : prints the command summary\n" ); fprintf( pAbc->Err, "\ttruth : truth table with most signficant bit first (e.g. 1000 for AND(a,b))\n" ); fprintf( pAbc->Err, "\tfile : file name with the truth table\n" ); @@ -3250,19 +3248,23 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv ) word * pTruth; int nBytes; int fReverse = 0; - int fBinary = 0; + int fHex = 1; + int fBinaryFile = 0; int c, i; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "rbh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "rxbh" ) ) != EOF ) { switch ( c ) { case 'r': fReverse ^= 1; break; + case 'x': + fHex ^= 1; + break; case 'b': - fBinary ^= 1; + fBinaryFile ^= 1; break; case 'h': goto usage; @@ -3300,19 +3302,22 @@ int IoCommandWriteTruths( Abc_Frame_t * pAbc, int argc, char **argv ) Gia_ManForEachCo( pAbc->pGia, pObj, i ) { pTruth = Gia_ObjComputeTruthTable( pAbc->pGia, pObj ); - if ( fBinary ) + if ( fBinaryFile ) fwrite( pTruth, nBytes, 1, pFile ); - else + else if ( fHex ) Extra_PrintHex( pFile, (unsigned *)pTruth, Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" ); + else + Extra_PrintBinary( pFile, (unsigned *)pTruth, 1 << Gia_ManPiNum(pAbc->pGia) ), fprintf( pFile, "\n" ); } fclose( pFile ); return 0; usage: - fprintf( pAbc->Err, "usage: &write_truths [-rbh] \n" ); + fprintf( pAbc->Err, "usage: &write_truths [-rxbh] \n" ); fprintf( pAbc->Err, "\t writes truth tables of each PO of GIA manager into a file\n" ); fprintf( pAbc->Err, "\t-r : toggle reversing bits in the truth table [default = %s]\n", fReverse? "yes":"no" ); - fprintf( pAbc->Err, "\t-b : toggle using binary format [default = %s]\n", fBinary? "yes":"no" ); + fprintf( pAbc->Err, "\t-x : toggle writing in the hex notation [default = %s]\n", fHex? "yes":"no" ); + fprintf( pAbc->Err, "\t-b : toggle using binary file format [default = %s]\n", fBinaryFile? "yes":"no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); return 1; diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index df53ebe0e..97cc97141 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -77,6 +77,32 @@ void Rtl_NtkCleanFile( char * pFileName ) fclose( pFile2 ); } +void Rtl_NtkCleanFile2( char * pFileName ) +{ + char * pBuffer, * pFileName2 = "_temp__.v"; + FILE * pFile = fopen( pFileName, "rb" ); + FILE * pFile2; + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return; + } + pFile2 = fopen( pFileName2, "wb" ); + if ( pFile2 == NULL ) + { + fclose( pFile ); + printf( "Cannot open file \"%s\" for writing.\n", pFileName2 ); + return; + } + pBuffer = ABC_ALLOC( char, MAX_LINE ); + while ( fgets( pBuffer, MAX_LINE, pFile ) != NULL ) + if ( !strstr(pBuffer, "//") ) + fputs( pBuffer, pFile2 ); + ABC_FREE( pBuffer ); + fclose( pFile ); + fclose( pFile2 ); +} + char * Wln_GetYosysName() { char * pYosysName = NULL; From ea5648db3f5cc48a2c370be43d8f313db3683967 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 16 Feb 2022 15:32:53 -0800 Subject: [PATCH 27/74] Improving truth table handling. --- src/base/abc/abcSop.c | 2 +- src/base/abci/abc.c | 17 ++++++++++++++++- src/base/io/io.c | 10 ++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/base/abc/abcSop.c b/src/base/abc/abcSop.c index a560a249f..8250102ac 100644 --- a/src/base/abc/abcSop.c +++ b/src/base/abc/abcSop.c @@ -924,7 +924,7 @@ int Abc_SopCheckReadTruth( Vec_Ptr_t * vRes, char * pToken, int fHex ) int Log2 = Abc_Base2Log( strlen(pToken) ); if ( (1 << Log2) != (int)strlen(pToken) ) { - printf( "The truth table length (%d) is not power-of-2.\n", strlen(pToken) ); + printf( "The truth table length (%d) is not power-of-2.\n", (int)strlen(pToken) ); Vec_PtrFreeData( vRes ); Vec_PtrShrink( vRes, 0 ); return 0; diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 1d97f5e41..c92917acb 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -37868,7 +37868,22 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) } } // compute the miter - pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose ); + if ( Gia_ManCiNum(pGias[0]) < 6 ) + { + Gia_Man_t * pGias0 = Gia_ManDup( pGias[0] ); + Gia_Man_t * pGias1 = Gia_ManDup( pGias[1] ); + for ( c = Gia_ManCiNum(pGias[0]); c < 6; c++ ) + { + Gia_ManAppendCi(pGias0); + Gia_ManAppendCi(pGias1); + } + pMiter = Gia_ManMiter( pGias0, pGias1, 0, !fUseNew, 0, 0, pPars->fVerbose ); + Gia_ManStop( pGias0 ); + Gia_ManStop( pGias1 ); + } + else + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose ); + if ( pMiter ) { if ( fDumpMiter ) diff --git a/src/base/io/io.c b/src/base/io/io.c index 72fd25bfb..26bfb1f4a 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -1142,7 +1142,17 @@ int IoCommandReadTruth( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; if ( fFile ) + { + FILE * pFile = fopen( argv[globalUtilOptind], "rb" ); + if ( pFile == NULL ) + { + printf( "The file \"%s\" cannot be found.\n", argv[globalUtilOptind] ); + return 1; + } + else + fclose( pFile ); pStr = Extra_FileReadContents( argv[globalUtilOptind] ); + } else pStr = argv[globalUtilOptind]; From 33fb7a809d9f076bd3a9e16585f075a96adb42ea Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 16 Feb 2022 21:23:21 -0800 Subject: [PATCH 28/74] Experiments with word-level data structures. --- abclib.dsp | 8 + src/base/main/mainInit.c | 4 + src/base/wlc/wlcCom.c | 220 ------------------------ src/base/wln/module.make | 2 + src/base/wln/wlnCom.c | 353 +++++++++++++++++++++++++++++++++++++++ src/base/wln/wlnGuide.c | 73 ++++++++ src/base/wln/wlnRead.c | 132 ++++++++++++++- src/base/wln/wlnRtl.c | 2 +- 8 files changed, 570 insertions(+), 224 deletions(-) create mode 100644 src/base/wln/wlnCom.c create mode 100644 src/base/wln/wlnGuide.c diff --git a/abclib.dsp b/abclib.dsp index f5e9f5f8b..23c2ce286 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -1131,6 +1131,14 @@ SOURCE=.\src\base\wln\wlnBlast.c # End Source File # Begin Source File +SOURCE=.\src\base\wln\wlnCom.c +# End Source File +# Begin Source File + +SOURCE=.\src\base\wln\wlnGuide.c +# End Source File +# Begin Source File + SOURCE=.\src\base\wln\wlnMem.c # End Source File # Begin Source File diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c index 693cea90b..d3ce672f5 100644 --- a/src/base/main/mainInit.c +++ b/src/base/main/mainInit.c @@ -49,6 +49,8 @@ extern void Scl_Init( Abc_Frame_t * pAbc ); extern void Scl_End( Abc_Frame_t * pAbc ); extern void Wlc_Init( Abc_Frame_t * pAbc ); extern void Wlc_End( Abc_Frame_t * pAbc ); +extern void Wln_Init( Abc_Frame_t * pAbc ); +extern void Wln_End( Abc_Frame_t * pAbc ); extern void Bac_Init( Abc_Frame_t * pAbc ); extern void Bac_End( Abc_Frame_t * pAbc ); extern void Cba_Init( Abc_Frame_t * pAbc ); @@ -116,6 +118,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc ) Load_Init( pAbc ); Scl_Init( pAbc ); Wlc_Init( pAbc ); + Wln_Init( pAbc ); Bac_Init( pAbc ); Cba_Init( pAbc ); Pla_Init( pAbc ); @@ -156,6 +159,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc ) Load_End( pAbc ); Scl_End( pAbc ); Wlc_End( pAbc ); + Wln_End( pAbc ); Bac_End( pAbc ); Cba_End( pAbc ); Pla_End( pAbc ); diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 2ea17169b..dd7a3e328 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -54,20 +54,12 @@ static int Abc_CommandInvPut ( Abc_Frame_t * pAbc, int argc, char ** argv ) static int Abc_CommandInvMin ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandSolve ( Abc_Frame_t * pAbc, int argc, char ** argv ); - static inline Wlc_Ntk_t * Wlc_AbcGetNtk( Abc_Frame_t * pAbc ) { return (Wlc_Ntk_t *)pAbc->pAbcWlc; } static inline void Wlc_AbcFreeNtk( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcWlc ) Wlc_NtkFree(Wlc_AbcGetNtk(pAbc)); } static inline void Wlc_AbcUpdateNtk( Abc_Frame_t * pAbc, Wlc_Ntk_t * pNtk ) { Wlc_AbcFreeNtk(pAbc); pAbc->pAbcWlc = pNtk; } static inline Vec_Int_t * Wlc_AbcGetInv( Abc_Frame_t * pAbc ) { return pAbc->pAbcWlcInv; } - -static inline Rtl_Lib_t * Wlc_AbcGetRtl( Abc_Frame_t * pAbc ) { return (Rtl_Lib_t *)pAbc->pAbcRtl; } -static inline void Wlc_AbcFreeRtl( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcRtl ) Rtl_LibFree(Wlc_AbcGetRtl(pAbc)); } -static inline void Wlc_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib ) { Wlc_AbcFreeRtl(pAbc); pAbc->pAbcRtl = pLib; } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -103,9 +95,6 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%show", Abc_CommandShow, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%test", Abc_CommandTest, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "inv_ps", Abc_CommandInvPs, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_print", Abc_CommandInvPrint, 0 ); Cmd_CommandAdd( pAbc, "Word level", "inv_check", Abc_CommandInvCheck, 0 ); @@ -1982,215 +1971,6 @@ usage: return 1; } - -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); - extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose ); - - FILE * pFile; - char * pFileName = NULL; - char * pTopModule= NULL; - int fBlast = 0; - int fInvert = 0; - int fTechMap = 1; - int fSkipStrash = 0; - int fCollapse = 0; - int c, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Tbismcvh" ) ) != EOF ) - { - switch ( c ) - { - case 'T': - if ( globalUtilOptind >= argc ) - { - Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); - goto usage; - } - pTopModule = argv[globalUtilOptind]; - globalUtilOptind++; - break; - case 'b': - fBlast ^= 1; - break; - case 'i': - fInvert ^= 1; - break; - case 's': - fSkipStrash ^= 1; - break; - case 'm': - fTechMap ^= 1; - break; - case 'c': - fCollapse ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - if ( argc != globalUtilOptind + 1 ) - { - printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); - return 0; - } - // get the file name - pFileName = argv[globalUtilOptind]; - if ( (pFile = fopen( pFileName, "r" )) == NULL ) - { - Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); - if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) - Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); - Abc_Print( 1, "\n" ); - return 0; - } - fclose( pFile ); - - // perform reading - if ( fBlast ) - { - Gia_Man_t * pNew = NULL; - if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); - else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); - else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) ) - pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); - else - { - printf( "Abc_CommandYosys(): Unknown file extension.\n" ); - return 0; - } - Abc_FrameUpdateGia( pAbc, pNew ); - } - else - { - Rtl_Lib_t * pLib = NULL; - if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) - pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); - else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) - pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); - else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) ) - pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); - else - { - printf( "Abc_CommandYosys(): Unknown file extension.\n" ); - return 0; - } - Wlc_AbcUpdateRtl( pAbc, pLib ); - } - return 0; -usage: - Abc_Print( -2, "usage: %%yosys [-T ] [-bismcvh] \n" ); - Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); - Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); - Abc_Print( -2, "\t-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" ); - Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); - Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); - Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); - Abc_Print( -2, "\t-c : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - -/**Function******************************************************************** - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -******************************************************************************/ -int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) -{ - extern void Rtl_LibPrintStats( Rtl_Lib_t * p ); - extern void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p ); - extern void Rtl_LibNormRanges( Rtl_Lib_t * pLib ); - extern void Rtl_LibOrderWires( Rtl_Lib_t * pLib ); - extern void Rtl_LibOrderCells( Rtl_Lib_t * pLib ); - extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); - extern void Rtl_LibBlast2( Rtl_Lib_t * pLib ); - extern void Rtl_LibReorderModules( Rtl_Lib_t * pLib ); - extern void Rtl_LibSolve( Rtl_Lib_t * pLib ); - extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); - - Gia_Man_t * pGia = NULL; - Rtl_Lib_t * pLib = Wlc_AbcGetRtl(pAbc); - int c, fOldBlast = 0, fPrepro = 0, fVerbose = 0; - Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF ) - { - switch ( c ) - { - case 'o': - fOldBlast ^= 1; - break; - case 'p': - fPrepro ^= 1; - break; - case 'v': - fVerbose ^= 1; - break; - case 'h': - goto usage; - default: - goto usage; - } - } - Rtl_LibPrintStats( pLib ); - //Rtl_LibPrint( NULL, pLib ); - Rtl_LibOrderWires( pLib ); - - if ( fOldBlast ) - { - Rtl_LibOrderCells( pLib ); - Rtl_LibBlast( pLib ); - } - else - Rtl_LibBlast2( pLib ); - //Rtl_LibReorderModules( pLib ); - //Rtl_LibPrintStats( pLib ); - - if ( fPrepro ) - Rtl_LibPreprocess( pLib ); - Rtl_LibSolve( pLib ); - - //Rtl_LibPrint( NULL, pLib ); - Wlc_AbcUpdateRtl( pAbc, NULL ); - Gia_ManStopP( &pGia ); - return 0; -usage: - Abc_Print( -2, "usage: %%solve [-opvh]\n" ); - Abc_Print( -2, "\t experiments with word-level networks\n" ); - Abc_Print( -2, "\t-o : toggle using old bit-blasting procedure [default = %s]\n", fOldBlast? "yes": "no" ); - Abc_Print( -2, "\t-p : toggle preprocessing for verification [default = %s]\n", fPrepro? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); - return 1; -} - - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wln/module.make b/src/base/wln/module.make index 7277f30b3..c1939126e 100644 --- a/src/base/wln/module.make +++ b/src/base/wln/module.make @@ -1,5 +1,7 @@ SRC += src/base/wln/wln.c \ src/base/wln/wlnBlast.c \ + src/base/wln/wlnCom.c \ + src/base/wln/wlnGuide.c \ src/base/wln/wlnMem.c \ src/base/wln/wlnNdr.c \ src/base/wln/wlnNtk.c \ diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c new file mode 100644 index 000000000..3db277857 --- /dev/null +++ b/src/base/wln/wlnCom.c @@ -0,0 +1,353 @@ +/**CFile**************************************************************** + + FileName [wlnCom.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wlnCom.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" +#include "base/main/mainInt.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandSolve ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); + +static inline Rtl_Lib_t * Wln_AbcGetRtl( Abc_Frame_t * pAbc ) { return (Rtl_Lib_t *)pAbc->pAbcRtl; } +static inline void Wln_AbcFreeRtl( Abc_Frame_t * pAbc ) { if ( pAbc->pAbcRtl ) Rtl_LibFree(Wln_AbcGetRtl(pAbc)); } +static inline void Wln_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib ) { Wln_AbcFreeRtl(pAbc); pAbc->pAbcRtl = pLib; } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_Init( Abc_Frame_t * pAbc ) +{ + Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%print", Abc_CommandPrint, 0 ); +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +void Wln_End( Abc_Frame_t * pAbc ) +{ + Wln_AbcUpdateRtl( pAbc, NULL ); +} + + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandYosys( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Wln_BlastSystemVerilog( char * pFileName, char * pTopModule, int fSkipStrash, int fInvert, int fTechMap, int fVerbose ); + extern Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCollapse, int fVerbose ); + + FILE * pFile; + char * pFileName = NULL; + char * pTopModule= NULL; + int fBlast = 0; + int fInvert = 0; + int fTechMap = 1; + int fSkipStrash = 0; + int fCollapse = 0; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Tbismcvh" ) ) != EOF ) + { + switch ( c ) + { + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); + goto usage; + } + pTopModule = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'b': + fBlast ^= 1; + break; + case 'i': + fInvert ^= 1; + break; + case 's': + fSkipStrash ^= 1; + break; + case 'm': + fTechMap ^= 1; + break; + case 'c': + fCollapse ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + printf( "Abc_CommandReadWlc(): Input file name should be given on the command line.\n" ); + return 0; + } + // get the file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = fopen( pFileName, "r" )) == NULL ) + { + Abc_Print( 1, "Cannot open input file \"%s\". ", pFileName ); + if ( (pFileName = Extra_FileGetSimilarName( pFileName, ".v", ".sv", NULL, NULL, NULL )) ) + Abc_Print( 1, "Did you mean \"%s\"?", pFileName ); + Abc_Print( 1, "\n" ); + return 0; + } + fclose( pFile ); + + // perform reading + if ( fBlast ) + { + Gia_Man_t * pNew = NULL; + if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) ) + pNew = Wln_BlastSystemVerilog( pFileName, pTopModule, fSkipStrash, fInvert, fTechMap, fVerbose ); + else + { + printf( "Abc_CommandYosys(): Unknown file extension.\n" ); + return 0; + } + Abc_FrameUpdateGia( pAbc, pNew ); + } + else + { + Rtl_Lib_t * pLib = NULL; + if ( !strcmp( Extra_FileNameExtension(pFileName), "v" ) ) + pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "sv" ) ) + pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "rtlil" ) ) + pLib = Wln_ReadSystemVerilog( pFileName, pTopModule, fCollapse, fVerbose ); + else + { + printf( "Abc_CommandYosys(): Unknown file extension.\n" ); + return 0; + } + Wln_AbcUpdateRtl( pAbc, pLib ); + } + return 0; +usage: + Abc_Print( -2, "usage: %%yosys [-T ] [-bismcvh] \n" ); + Abc_Print( -2, "\t reads Verilog or SystemVerilog using Yosys\n" ); + Abc_Print( -2, "\t-T : specify the top module name (default uses \"-auto-top\"\n" ); + Abc_Print( -2, "\t-b : toggle bit-blasting the design into an AIG using Yosys [default = %s]\n", fBlast? "yes": "no" ); + Abc_Print( -2, "\t-i : toggle interting the outputs (useful for miters) [default = %s]\n", fInvert? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle no structural hashing during bit-blasting [default = %s]\n", fSkipStrash? "no strash": "strash" ); + Abc_Print( -2, "\t-m : toggle using \"techmap\" to blast operators [default = %s]\n", fTechMap? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle collapsing design hierarchy using Yosys [default = %s]\n", fCollapse? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandPrint( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Rtl_LibPrintStats( Rtl_Lib_t * p ); + extern void Rtl_LibPrintHieStats( Rtl_Lib_t * p ); + extern void Rtl_LibPrint( char * pFileName, Rtl_Lib_t * p ); + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + int c, fHie = 0, fDesign = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "pdvh" ) ) != EOF ) + { + switch ( c ) + { + case 'p': + fHie ^= 1; + break; + case 'd': + fDesign ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pLib == NULL ) + { + printf( "The design is not entered.\n" ); + return 1; + } + Rtl_LibPrintStats( pLib ); + if ( fHie ) + Rtl_LibPrintHieStats( pLib ); + if ( fDesign ) + Rtl_LibPrint( NULL, pLib ); + return 0; +usage: + Abc_Print( -2, "usage: %%print [-pdvh]\n" ); + Abc_Print( -2, "\t print statistics about the hierarchical design\n" ); + Abc_Print( -2, "\t-p : toggle printing of the hierarchy [default = %s]\n", fHie? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle printing of the design [default = %s]\n", fDesign? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t : text file name with guidance for solving\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); + extern void Rtl_LibBlast2( Rtl_Lib_t * pLib ); + extern void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ); + extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); + extern void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ); + + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + int c, fOldBlast = 0, fPrepro = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "opvh" ) ) != EOF ) + { + switch ( c ) + { + case 'o': + fOldBlast ^= 1; + break; + case 'p': + fPrepro ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pLib == NULL ) + { + printf( "The design is not entered.\n" ); + return 1; + } + if ( argc == globalUtilOptind + 1 ) + { + char * pFileName = argv[globalUtilOptind]; + FILE * pFile = fopen( pFileName, "r" ); + if ( pFile == NULL ) + { + Abc_Print( -1, "Cannot open file \"%s\" with the input test patterns.\n", pFileName ); + return 0; + } + fclose( pFile ); + printf( "Using guidance from file \"%s\".\n", pFileName ); + Wln_SolveWithGuidance( pFileName, pLib ); + } + else + { + printf( "Solving the miter without guidance.\n" ); + if ( fOldBlast ) + Rtl_LibBlast( pLib ); + else + Rtl_LibBlast2( pLib ); + if ( fPrepro ) + Rtl_LibPreprocess( pLib ); + Rtl_LibSolve( pLib, NULL ); + } + return 0; +usage: + Abc_Print( -2, "usage: %%solve [-opvh] \n" ); + Abc_Print( -2, "\t solving properties for the hierarchical design\n" ); + Abc_Print( -2, "\t-o : toggle using old bit-blasting procedure [default = %s]\n", fOldBlast? "yes": "no" ); + Abc_Print( -2, "\t-p : toggle preprocessing for verification [default = %s]\n", fPrepro? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t : text file name with guidance for solving\n"); + return 1; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnGuide.c b/src/base/wln/wlnGuide.c new file mode 100644 index 000000000..abe9a6d8e --- /dev/null +++ b/src/base/wln/wlnGuide.c @@ -0,0 +1,73 @@ +/**CFile**************************************************************** + + FileName [wln.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Word-level network.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - September 23, 2018.] + + Revision [$Id: wln.c,v 1.00 2018/09/23 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "wln.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ) +{ + char Buffer[1000] = {'\\'}, * pBuffer = Buffer+1; + Vec_Int_t * vTokens = Vec_IntAlloc( 100 ); + FILE * pFile = fopen( pFileName, "rb" ); + while ( fscanf( pFile, "%s", pBuffer ) == 1 ) + { + if ( pBuffer[(int)strlen(pBuffer)-1] == '\r' ) + pBuffer[(int)strlen(pBuffer)-1] = 0; + if ( !strcmp(pBuffer, "prove") && Vec_IntSize(vTokens) % 4 == 3 ) // account for "property" + Vec_IntPush( vTokens, -1 ); + if ( Vec_IntSize(vTokens) % 4 == 2 || Vec_IntSize(vTokens) % 4 == 3 ) + Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, Buffer, NULL) ); + else + Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, pBuffer, NULL) ); + } + fclose( pFile ); + if ( Vec_IntSize(vTokens) % 4 == 3 ) // account for "property" + Vec_IntPush( vTokens, -1 ); + assert( Vec_IntSize(vTokens) % 4 == 0 ); + return vTokens; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 62cb70c62..bc4211acb 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -78,6 +78,8 @@ struct Rtl_Ntk_t_ static inline int Rtl_LibNtkNum( Rtl_Lib_t * pLib ) { return Vec_PtrSize(pLib->vNtks); } static inline Rtl_Ntk_t * Rtl_LibNtk( Rtl_Lib_t * pLib, int i ) { return (Rtl_Ntk_t *)Vec_PtrEntry(pLib->vNtks, i); } static inline Rtl_Ntk_t * Rtl_LibTop( Rtl_Lib_t * pLib ) { return Rtl_LibNtk( pLib, Rtl_LibNtkNum(pLib)-1 ); } +static inline char * Rtl_LibStr( Rtl_Lib_t * pLib, int h ) { return Abc_NamStr(pLib->pManName, h); } +static inline int Rtl_LibStrId( Rtl_Lib_t * pLib, char * s ) { return Abc_NamStrFind(pLib->pManName, s); } static inline Rtl_Ntk_t * Rtl_NtkModule( Rtl_Ntk_t * p, int i ) { return Rtl_LibNtk( p->pLib, i ); } @@ -243,6 +245,50 @@ void Rtl_NtkPrintStats( Rtl_Ntk_t * p, int nNameSymbs ) //Rtl_NtkPrintOpers( p ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Rtl_NtkPrintHieStats( Rtl_Ntk_t * p, int nOffset ) +{ + Vec_Int_t * vFound = Vec_IntAlloc( 100 ); + int i, * pCell; + for ( i = 0; i < 5*(nOffset-1); i++ ) + printf( " " ); + if ( nOffset ) + printf( "|--> " ); + printf( "%s\n", Rtl_NtkName(p) ); + Rtl_NtkForEachCell( p, pCell, i ) + if ( Rtl_CellModule(pCell) >= ABC_INFINITY ) + { + Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); + assert( pCell[6] == pModel->nInputs+pModel->nOutputs ); + if ( Vec_IntFind(vFound, pModel->NameId) >= 0 ) + continue; + Vec_IntPush( vFound, pModel->NameId ); + Rtl_NtkPrintHieStats( pModel, nOffset+1 ); + } + Vec_IntFree( vFound ); +} +void Rtl_LibPrintHieStats( Rtl_Lib_t * p ) +{ + Rtl_Ntk_t * pNtk; int i; + printf( "Hierarchy found in \"%s\":\n", p->pSpec ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + { + printf( "\n" ); + printf( "MODULE %d: ", i ); + Rtl_NtkPrintHieStats( pNtk, 0 ); + } +} + /**Function************************************************************* Synopsis [] @@ -1398,6 +1444,7 @@ Rtl_Lib_t * Rtl_LibReadFile( char * pFileName, char * pFileSpec ) i = Rtl_NtkReadAttribute2( p, i+1 ); Rtl_LibSetParents( p ); Rtl_LibReorderModules( p ); + Rtl_LibOrderWires( p ); return p; } @@ -1733,7 +1780,7 @@ char * Rtl_ShortenName( char * pName, int nSize ) return pName; Buffer[0] = 0; strcat( Buffer, pName ); - Buffer[nSize-4] = ' '; + //Buffer[nSize-4] = ' '; Buffer[nSize-3] = '.'; Buffer[nSize-2] = '.'; Buffer[nSize-1] = '.'; @@ -1941,6 +1988,7 @@ void Rtl_NtkBlastPrepareInputs( Rtl_Ntk_t * p, int * pCell ) } void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver ) { + //char * pName = Rtl_NtkName(p); assert( pDriver[0] != -1 ); if ( pDriver[0] == -3 ) { @@ -1981,6 +2029,7 @@ Gia_Man_t * Rtl_NtkBlast2( Rtl_Ntk_t * p ) int i, b, nBits = Rtl_NtkRangeWires( p ); char Buffer[100]; static int counter = 0; Vec_IntFill( &p->vLits, nBits, -1 ); +printf( "Blasting %s...\r", Rtl_NtkName(p) ); Rtl_NtkMapWires( p, 0 ); Rtl_NtkBlastMap( p, nBits ); assert( p->pGia == NULL ); @@ -2066,11 +2115,11 @@ finish: //Rtl_LibBlast( pLib ); Rtl_LibBlast2( pLib ); } -void Rtl_LibSolve( Rtl_Lib_t * pLib ) +void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) { extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); abctime clk = Abc_Clock(); int Status; - Rtl_Ntk_t * pTop = Rtl_LibTop( pLib ); + Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib ); Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pTop->pGia, 1000000, 0 ); int RetValue = Gia_ManAndNum(pSwp) == 0; Gia_ManStop( pSwp ); @@ -2092,6 +2141,83 @@ void Rtl_LibSolve( Rtl_Lib_t * pLib ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_SolveEqual( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) +{ + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); + printf( "Proving equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); +/* + if ( Gia_ManCiNum(pNtk1->pGia) != Gia_ManCiNum(pNtk2->pGia) || + Gia_ManCoNum(pNtk1->pGia) != Gia_ManCoNum(pNtk2->pGia) ) + { + printf( "The number of inputs/outputs does not match.\n" ); + } + else + { + int Status = Cec_ManVerifyTwo( pNtk1->pGia, pNtk2->pGia, 0 ); + if ( Status == 1 ) + printf( "The networks are equivalence.\n" ); + else + printf( "The networks are NOT equivalent.\n" ); + } +*/ +} +void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) +{ + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); + printf( "Proving inverse equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); +} +void Wln_SolveProperty( Rtl_Lib_t * p, int iNtk ) +{ + Rtl_Ntk_t * pNtk = Rtl_LibNtk( p, iNtk ); + printf( "Proving property \"%s\".\n", Rtl_NtkName(pNtk) ); + Rtl_LibSolve( p, pNtk ); +} +void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ) +{ + extern Vec_Int_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ); + Vec_Int_t * vGuide = Wln_ReadGuidance( pFileName, p->pManName ); int i; + Vec_IntFillExtra( p->vMap, Abc_NamObjNumMax(p->pManName), -1 ); + Rtl_LibBlast2( p ); + for ( i = 0; i < Vec_IntSize(vGuide); i += 4 ) + { + int Prove = Vec_IntEntry( vGuide, i+0 ); + int Type = Vec_IntEntry( vGuide, i+1 ); + int Name1 = Vec_IntEntry( vGuide, i+2 ); + int Name2 = Vec_IntEntry( vGuide, i+3 ); + int iNtk1 = Rtl_LibFindModule( p, Name1 ); + int iNtk2 = Name2 == -1 ? -1 : Rtl_LibFindModule( p, Name2 ); + if ( Prove != Rtl_LibStrId(p, "prove") ) + printf( "Unknown task in line %d.\n", i/4 ); + else if ( iNtk1 == -1 ) + printf( "Network %s cannot be found in this design.\n", Rtl_LibStr(p, Name1) ); + else + { + if ( Type == Rtl_LibStrId(p, "equal") ) + Wln_SolveEqual( p, iNtk1, iNtk2 ); + else if ( Type == Rtl_LibStrId(p, "inverse") ) + Wln_SolveInverse( p, iNtk1, iNtk2 ); + else if ( Type == Rtl_LibStrId(p, "property") ) + Wln_SolveProperty( p, iNtk1 ); + continue; + } + break; + } + Vec_IntFree( vGuide ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wln/wlnRtl.c b/src/base/wln/wlnRtl.c index 97cc97141..fa0f0cd5c 100644 --- a/src/base/wln/wlnRtl.c +++ b/src/base/wln/wlnRtl.c @@ -145,7 +145,7 @@ Rtl_Lib_t * Wln_ReadSystemVerilog( char * pFileName, char * pTopModule, int fCol return Rtl_LibReadFile( pFileName, pFileName ); sprintf( Command, "%s -qp \"read_verilog %s%s; hierarchy %s%s; %sproc; write_rtlil %s\"", Wln_GetYosysName(), fSVlog ? "-sv ":"", pFileName, - pTopModule ? "-top " : "-auto-top", + pTopModule ? "-top " : "", pTopModule ? pTopModule : "", fCollapse ? "flatten; " : "", pFileTemp ); From c93c4053d3528efd709a3b5bf78023abd1d183e5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 18 Feb 2022 13:29:38 +1100 Subject: [PATCH 29/74] Fix compile error on targets with unsigned char MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit abc is failing to compile on ppc64le because char is unsigned by default: src/misc/extra/extraUtilMisc.c: In function ‘void abc::Extra_TruthExpand(int, int, unsigned int*, unsigned int, unsigned int*)’: src/misc/extra/extraUtilMisc.c:1550:5: error: narrowing conversion of ‘-1’ from ‘int’ to ‘char’ inside { } [-Wnarrowing] --- src/misc/extra/extraUtilMisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/misc/extra/extraUtilMisc.c b/src/misc/extra/extraUtilMisc.c index c38369cdf..e081e9c6e 100644 --- a/src/misc/extra/extraUtilMisc.c +++ b/src/misc/extra/extraUtilMisc.c @@ -1290,7 +1290,7 @@ void Extra_TruthExpand( int nVars, int nWords, unsigned * puTruth, unsigned uPha { 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF }, { 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF } }; - static char Cases[256] = { + static signed char Cases[256] = { 0, // 00000000 0, // 00000001 1, // 00000010 From b442c749e392f4b794556402d8671de869fd81b2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 18 Feb 2022 10:51:49 -0800 Subject: [PATCH 30/74] Suggested change to prevent ABC from crashing when compiled on Windows. --- src/base/cmd/cmdLoad.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/base/cmd/cmdLoad.c b/src/base/cmd/cmdLoad.c index accd9440f..bd511feca 100644 --- a/src/base/cmd/cmdLoad.c +++ b/src/base/cmd/cmdLoad.c @@ -114,7 +114,8 @@ Vec_Ptr_t * CmdCollectFileNames() { Vec_Ptr_t * vFileNames; struct _finddata_t c_file; - long hFile; + //long hFile; + ABC_PTRINT_T hFile; if( (hFile = _findfirst( "*.exe", &c_file )) == -1L ) { // Abc_Print( 0, "No files with extention \"%s\" in the current directory.\n", "exe" ); From 31519bd6d6c9cff4691019f72e0faf72e37bde88 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 18 Feb 2022 14:11:17 -0800 Subject: [PATCH 31/74] Similar changes suggested in other places. --- src/base/cmd/cmd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index a00424432..fe7286b77 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -1161,7 +1161,7 @@ int CmdCommandScanDir( Abc_Frame_t * pAbc, int argc, char **argv ) struct _finddata_t c_file; char * pDirStr = NULL; char* pDirCur = NULL; - long hFile; + ABC_PTRINT_T hFile; char c; Extra_UtilGetoptReset(); @@ -1354,7 +1354,7 @@ void CnfDupFileUnzip( char * pOldName ) int CmdCommandRenameFiles( Abc_Frame_t * pAbc, int argc, char **argv ) { struct _finddata_t c_file; - long hFile; + ABC_PTRINT_T hFile; char pNewName[1000]; char * pDirStr = NULL; char * pDirCur = NULL; @@ -1515,7 +1515,7 @@ usage: int CmdCommandLs( Abc_Frame_t * pAbc, int argc, char **argv ) { struct _finddata_t c_file; - long hFile; + ABC_PTRINT_T hFile; int fLong = 0; int fOnlyBLIF = 0; char Buffer[25]; @@ -1618,7 +1618,7 @@ usage: int CmdCommandScrGen( Abc_Frame_t * pAbc, int argc, char **argv ) { struct _finddata_t c_file; - long hFile; + ABC_PTRINT_T hFile; FILE * pFile = NULL; char * pFileStr = "test.s"; char * pDirStr = NULL; From bcf21e46778f63ab4ce490b57648421a2b4d7e28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 22 Feb 2022 21:14:48 -0800 Subject: [PATCH 32/74] Intersection a bug in rewrite/refactor. --- src/base/abc/abc.h | 2 +- src/base/abc/abcAig.c | 5 ++++- src/base/abci/abc.c | 42 ++++++++++++++++++++++++++++--------- src/base/abci/abcRefactor.c | 34 ++++++++++++++++++------------ src/base/abci/abcRestruct.c | 2 +- src/base/abci/abcResub.c | 2 +- src/base/abci/abcRewrite.c | 31 ++++++++++++++++----------- src/base/abci/abcRr.c | 5 +---- src/bool/dec/decAbc.c | 7 ++++--- 9 files changed, 84 insertions(+), 46 deletions(-) diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index eea66f297..b4e22a38c 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -559,7 +559,7 @@ extern ABC_DLL Abc_Obj_t * Abc_AigOr( Abc_Aig_t * pMan, Abc_Obj_t * p0, A extern ABC_DLL Abc_Obj_t * Abc_AigXor( Abc_Aig_t * pMan, Abc_Obj_t * p0, Abc_Obj_t * p1 ); extern ABC_DLL Abc_Obj_t * Abc_AigMux( Abc_Aig_t * pMan, Abc_Obj_t * pC, Abc_Obj_t * p1, Abc_Obj_t * p0 ); extern ABC_DLL Abc_Obj_t * Abc_AigMiter( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs, int fImplic ); -extern ABC_DLL void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel ); +extern ABC_DLL int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel ); extern ABC_DLL void Abc_AigDeleteNode( Abc_Aig_t * pMan, Abc_Obj_t * pOld ); extern ABC_DLL void Abc_AigRehash( Abc_Aig_t * pMan ); extern ABC_DLL int Abc_AigNodeHasComplFanoutEdge( Abc_Obj_t * pNode ); diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index d3347a136..8469789b4 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -847,7 +847,7 @@ Abc_Obj_t * Abc_AigMiter2( Abc_Aig_t * pMan, Vec_Ptr_t * vPairs ) SeeAlso [] ***********************************************************************/ -void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel ) +int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fUpdateLevel ) { assert( Vec_PtrSize(pMan->vStackReplaceOld) == 0 ); assert( Vec_PtrSize(pMan->vStackReplaceNew) == 0 ); @@ -859,6 +859,8 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int f { pOld = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceOld ); pNew = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceNew ); + if ( Abc_ObjFanoutNum(pOld) != 0 ) + return 0; Abc_AigReplace_int( pMan, pOld, pNew, fUpdateLevel ); } if ( fUpdateLevel ) @@ -867,6 +869,7 @@ void Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int f if ( pMan->pNtkAig->vLevelsR ) Abc_AigUpdateLevelR_int( pMan ); } + return 1; } /**Function************************************************************* diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index c92917acb..06d7cb081 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -7312,8 +7312,8 @@ usage: ***********************************************************************/ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); - int c; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup; + int c, RetValue; int fUpdateLevel; int fPrecompute; int fUseZeros; @@ -7383,10 +7383,21 @@ int Abc_CommandRewrite( Abc_Frame_t * pAbc, int argc, char ** argv ) } // modify the current network - if ( !Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable ) ) + pDup = Abc_NtkDup( pNtk ); + RetValue = Abc_NtkRewrite( pNtk, fUpdateLevel, fUseZeros, fVerbose, fVeryVerbose, fPlaceEnable ); + if ( RetValue == -1 ) { - Abc_Print( -1, "Rewriting has failed.\n" ); - return 1; + Abc_FrameReplaceCurrentNetwork( pAbc, pDup ); + printf( "An error occurred during computation. The original network is restored.\n" ); + } + else + { + Abc_NtkDelete( pDup ); + if ( RetValue == 0 ) + { + Abc_Print( 0, "Rewriting has failed.\n" ); + return 1; + } } return 0; @@ -7415,8 +7426,8 @@ usage: ***********************************************************************/ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); - int c; + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc), * pDup; + int c, RetValue; int nNodeSizeMax; int nConeSizeMax; int fUpdateLevel; @@ -7506,10 +7517,21 @@ int Abc_CommandRefactor( Abc_Frame_t * pAbc, int argc, char ** argv ) } // modify the current network - if ( !Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ) ) + pDup = Abc_NtkDup( pNtk ); + RetValue = Abc_NtkRefactor( pNtk, nNodeSizeMax, nConeSizeMax, fUpdateLevel, fUseZeros, fUseDcs, fVerbose ); + if ( RetValue == -1 ) { - Abc_Print( -1, "Refactoring has failed.\n" ); - return 1; + Abc_FrameReplaceCurrentNetwork( pAbc, pDup ); + printf( "An error occurred during computation. The original network is restored.\n" ); + } + else + { + Abc_NtkDelete( pDup ); + if ( RetValue == 0 ) + { + Abc_Print( 0, "Refactoring has failed.\n" ); + return 1; + } } return 0; diff --git a/src/base/abci/abcRefactor.c b/src/base/abci/abcRefactor.c index 3cc6d7936..8ec5944fa 100644 --- a/src/base/abci/abcRefactor.c +++ b/src/base/abci/abcRefactor.c @@ -325,7 +325,7 @@ void Abc_NtkManRefPrintStats( Abc_ManRef_t * p ) ***********************************************************************/ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose ) { - extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Abc_ManRef_t * pManRef; Abc_ManCut_t * pManCut; @@ -333,7 +333,7 @@ int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int f Vec_Ptr_t * vFanins; Abc_Obj_t * pNode; abctime clk, clkStart = Abc_Clock(); - int i, nNodes; + int i, nNodes, RetValue = 1; assert( Abc_NtkIsStrash(pNtk) ); // cleanup the AIG @@ -377,7 +377,12 @@ pManRef->timeRes += Abc_Clock() - clk; continue; // acceptable replacement found, update the graph clk = Abc_Clock(); - Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain ); + if ( !Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain ) ) + { + Dec_GraphFree( pFForm ); + RetValue = -1; + break; + } pManRef->timeNtk += Abc_Clock() - clk; Dec_GraphFree( pFForm ); } @@ -394,18 +399,21 @@ pManRef->timeTotal = Abc_Clock() - clkStart; // put the nodes into the DFS order and reassign their IDs Abc_NtkReassignIds( pNtk ); // Abc_AigCheckFaninOrder( pNtk->pManFunc ); - // fix the levels - if ( fUpdateLevel ) - Abc_NtkStopReverseLevels( pNtk ); - else - Abc_NtkLevel( pNtk ); - // check - if ( !Abc_NtkCheck( pNtk ) ) + if ( RetValue != -1 ) { - printf( "Abc_NtkRefactor: The network check has failed.\n" ); - return 0; + // fix the levels + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRefactor: The network check has failed.\n" ); + return 0; + } } - return 1; + return RetValue; } diff --git a/src/base/abci/abcRestruct.c b/src/base/abci/abcRestruct.c index ef5dd4514..87f152383 100644 --- a/src/base/abci/abcRestruct.c +++ b/src/base/abci/abcRestruct.c @@ -105,7 +105,7 @@ static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p ); ***********************************************************************/ int Abc_NtkRestructure( Abc_Ntk_t * pNtk, int nCutMax, int fUpdateLevel, int fUseZeros, int fVerbose ) { - extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Abc_ManRst_t * pManRst; Cut_Man_t * pManCut; diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c index b8934e237..dc1b60368 100644 --- a/src/base/abci/abcResub.c +++ b/src/base/abci/abcResub.c @@ -136,7 +136,7 @@ extern abctime s_ResubTime; ***********************************************************************/ int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose ) { - extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Abc_ManRes_t * pManRes; Abc_ManCut_t * pManCut; diff --git a/src/base/abci/abcRewrite.c b/src/base/abci/abcRewrite.c index 0b0881a6c..1da7e4e80 100644 --- a/src/base/abci/abcRewrite.c +++ b/src/base/abci/abcRewrite.c @@ -60,14 +60,14 @@ extern void Abc_PlaceUpdate( Vec_Ptr_t * vAddedCells, Vec_Ptr_t * vUpdatedNets ***********************************************************************/ int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable ) { - extern void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + extern int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); ProgressBar * pProgress; Cut_Man_t * pManCut; Rwr_Man_t * pManRwr; Abc_Obj_t * pNode; // Vec_Ptr_t * vAddedCells = NULL, * vUpdatedNets = NULL; Dec_Graph_t * pGraph; - int i, nNodes, nGain, fCompl; + int i, nNodes, nGain, fCompl, RetValue = 1; abctime clk, clkStart = Abc_Clock(); assert( Abc_NtkIsStrash(pNtk) ); @@ -138,7 +138,11 @@ Rwr_ManAddTimeCuts( pManRwr, Abc_Clock() - clk ); // complement the FF if needed if ( fCompl ) Dec_GraphComplement( pGraph ); clk = Abc_Clock(); - Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); + if ( !Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ) ) + { + RetValue = -1; + break; + } Rwr_ManAddTimeUpdate( pManRwr, Abc_Clock() - clk ); if ( fCompl ) Dec_GraphComplement( pGraph ); @@ -175,17 +179,20 @@ Rwr_ManAddTimeTotal( pManRwr, Abc_Clock() - clkStart ); } // Abc_AigCheckFaninOrder( pNtk->pManFunc ); // fix the levels - if ( fUpdateLevel ) - Abc_NtkStopReverseLevels( pNtk ); - else - Abc_NtkLevel( pNtk ); - // check - if ( !Abc_NtkCheck( pNtk ) ) + if ( RetValue >= 0 ) { - printf( "Abc_NtkRewrite: The network check has failed.\n" ); - return 0; + if ( fUpdateLevel ) + Abc_NtkStopReverseLevels( pNtk ); + else + Abc_NtkLevel( pNtk ); + // check + if ( !Abc_NtkCheck( pNtk ) ) + { + printf( "Abc_NtkRewrite: The network check has failed.\n" ); + return 0; + } } - return 1; + return RetValue; } diff --git a/src/base/abci/abcRr.c b/src/base/abci/abcRr.c index 52d1fd328..86c5f13ea 100644 --- a/src/base/abci/abcRr.c +++ b/src/base/abci/abcRr.c @@ -397,10 +397,7 @@ int Abc_NtkRRUpdate( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, Abc_Obj_t * pFanin, Ab else assert( 0 ); // replace if ( pFanout == NULL ) - { - Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pNode, pNodeNew, 1 ); - return 1; - } + return Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pNode, pNodeNew, 1 ); // find the fanout after redundancy removal if ( pNode == Abc_ObjFanin0(pFanout) ) pFanoutNew = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, Abc_ObjNotCond(pNodeNew,Abc_ObjFaninC0(pFanout)), Abc_ObjChild1(pFanout) ); diff --git a/src/bool/dec/decAbc.c b/src/bool/dec/decAbc.c index 6602702c6..e440a6525 100644 --- a/src/bool/dec/decAbc.c +++ b/src/bool/dec/decAbc.c @@ -237,20 +237,21 @@ int Dec_GraphToNetworkCount( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMa SeeAlso [] ***********************************************************************/ -void Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ) +int Dec_GraphUpdateNetwork( Abc_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ) { extern Abc_Obj_t * Dec_GraphToNetwork( Abc_Ntk_t * pNtk, Dec_Graph_t * pGraph ); Abc_Obj_t * pRootNew; Abc_Ntk_t * pNtk = pRoot->pNtk; - int nNodesNew, nNodesOld; + int nNodesNew, nNodesOld, RetValue; nNodesOld = Abc_NtkNodeNum(pNtk); // create the new structure of nodes pRootNew = Dec_GraphToNetwork( pNtk, pGraph ); // remove the old nodes - Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel ); + RetValue = Abc_AigReplace( (Abc_Aig_t *)pNtk->pManFunc, pRoot, pRootNew, fUpdateLevel ); // compare the gains nNodesNew = Abc_NtkNodeNum(pNtk); //assert( nGain <= nNodesOld - nNodesNew ); + return RetValue; } From 3186a82f65ea8a5847dcf847423cd7f315a3a2ca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 23 Feb 2022 10:11:23 -0800 Subject: [PATCH 33/74] Intersection a bug in rewrite/refactor. --- src/base/abc/abcAig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/abc/abcAig.c b/src/base/abc/abcAig.c index 8469789b4..636fe30ae 100644 --- a/src/base/abc/abcAig.c +++ b/src/base/abc/abcAig.c @@ -859,7 +859,7 @@ int Abc_AigReplace( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, int fU { pOld = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceOld ); pNew = (Abc_Obj_t *)Vec_PtrPop( pMan->vStackReplaceNew ); - if ( Abc_ObjFanoutNum(pOld) != 0 ) + if ( Abc_ObjFanoutNum(pOld) == 0 ) return 0; Abc_AigReplace_int( pMan, pOld, pNew, fUpdateLevel ); } From 6606c18c708deb1844b3bf05d6fa9b5e05003579 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 25 Feb 2022 22:15:13 -0800 Subject: [PATCH 34/74] Interleaved variable ordering during bit-blasting. --- src/base/wlc/wlcBlast.c | 44 +++++++++++++++++++++++++++++++++++++++++ src/base/wlc/wlcCom.c | 19 +++++++++++++++--- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index c6edb3aba..cf7ae5df2 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -2588,6 +2588,50 @@ Gia_Man_t * Wlc_BlastArray( char * pFileName ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis ) +{ + Vec_Int_t * vPerm = Vec_IntAlloc( 100 ); + Vec_Int_t * vSizes = Vec_IntAlloc( 100 ); + Vec_Int_t * vOffs = Vec_IntAlloc( 100 ); + Wlc_Obj_t * pObj; + int i, k, First, Size, nBitCis = 0, fChange = 1; + Wlc_NtkForEachPi( pNtk, pObj, i ) + { + Vec_IntPush( vOffs, nBitCis ); + Vec_IntPush( vSizes, Wlc_ObjRange(pObj) ); + nBitCis += Wlc_ObjRange(pObj); + } + for ( k = 0; fChange; k++ ) + { + fChange = 0; + Vec_IntForEachEntryTwo( vOffs, vSizes, First, Size, i ) + if ( k < Size ) + { + Vec_IntPush( vPerm, First+k ); + fChange = 1; + } + } + assert( Vec_IntSize(vPerm) == nBitCis ); + Vec_IntFree( vOffs ); + Vec_IntFree( vSizes ); + Vec_IntReverseOrder( vPerm ); + for ( i = Vec_IntSize(vPerm); i < nPis; i++ ) + Vec_IntPush( vPerm, i ); + //Vec_IntPrint( vPerm ); + return vPerm; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index dd7a3e328..37ecf2c77 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1031,12 +1031,12 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Wlc_NtkPrintInputInfo( Wlc_Ntk_t * pNtk ); Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0, fPrintInputInfo = 0; + Gia_Man_t * pNew = NULL; int c, fMiter = 0, fDumpNames = 0, fPrintInputInfo = 0, fReorder = 0; Wlc_BstPar_t Par, * pPar = &Par; Wlc_BstParDefault( pPar ); pPar->nOutputRange = 2; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestnizvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestrnizvh" ) ) != EOF ) { switch ( c ) { @@ -1118,6 +1118,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) pPar->fCreateMiter ^= 1; fMiter ^= 1; break; + case 'r': + fReorder ^= 1; + break; case 'n': fDumpNames ^= 1; break; @@ -1197,10 +1200,19 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Finished dumping file \"pio_name_map.txt\" containing PI/PO name mapping.\n" ); } } + if ( fReorder ) + { + extern Vec_Int_t * Wlc_ComputePerm( Wlc_Ntk_t * pNtk, int nPis ); + Vec_Int_t * vPiPerm = Wlc_ComputePerm( pNtk, Gia_ManPiNum(pNew) ); + Gia_Man_t * pTemp = Gia_ManDupPerm( pNew, vPiPerm ); + Vec_IntFree( vPiPerm ); + Gia_ManStop( pNew ); + pNew = pTemp; + } Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestnizvh]\n" ); + Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestrnizvh]\n" ); Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" ); Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput ); Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange ); @@ -1217,6 +1229,7 @@ usage: Abc_Print( -2, "\t-e : toggle creating miter with output word bits combined [default = %s]\n", pPar->fCreateWordMiter? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" ); Abc_Print( -2, "\t-t : toggle creating regular multi-output miter [default = %s]\n", fMiter? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle using interleaved variable ordering [default = %s]\n", fReorder? "yes": "no" ); Abc_Print( -2, "\t-n : toggle dumping signal names into a text file [default = %s]\n", fDumpNames? "yes": "no" ); Abc_Print( -2, "\t-i : toggle to print input names after blasting [default = %s]\n", fPrintInputInfo ? "yes": "no" ); Abc_Print( -2, "\t-z : toggle saving flop names after blasting [default = %s]\n", pPar->fSaveFfNames ? "yes": "no" ); From 32693e9857c21c03257ec620fb2439ad36d381e3 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 5 Mar 2022 20:58:38 -0800 Subject: [PATCH 35/74] Experiments with word-level data structures. --- src/base/wlc/wlcCom.c | 2 +- src/base/wln/wlnCom.c | 4 +- src/base/wln/wlnGuide.c | 54 +++++++++---- src/base/wln/wlnRead.c | 175 +++++++++++++++++++++++++++++++++++----- 4 files changed, 195 insertions(+), 40 deletions(-) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 37ecf2c77..dcddd0423 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -21,7 +21,7 @@ #include "wlc.h" #include "base/wln/wln.h" #include "base/main/mainInt.h" -#include "aig/miniaig/ndr.h" +//#include "aig/miniaig/ndr.h" ABC_NAMESPACE_IMPL_START diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index 3db277857..90ac4faa8 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -276,7 +276,7 @@ usage: int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); - extern void Rtl_LibBlast2( Rtl_Lib_t * pLib ); + extern void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots ); extern void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ); extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); extern void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ); @@ -327,7 +327,7 @@ int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fOldBlast ) Rtl_LibBlast( pLib ); else - Rtl_LibBlast2( pLib ); + Rtl_LibBlast2( pLib, NULL ); if ( fPrepro ) Rtl_LibPreprocess( pLib ); Rtl_LibSolve( pLib, NULL ); diff --git a/src/base/wln/wlnGuide.c b/src/base/wln/wlnGuide.c index abe9a6d8e..b7e656eba 100644 --- a/src/base/wln/wlnGuide.c +++ b/src/base/wln/wlnGuide.c @@ -41,26 +41,48 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -Vec_Int_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ) +int Wln_ReadFindToken( char * pToken, Abc_Nam_t * p ) { - char Buffer[1000] = {'\\'}, * pBuffer = Buffer+1; - Vec_Int_t * vTokens = Vec_IntAlloc( 100 ); - FILE * pFile = fopen( pFileName, "rb" ); - while ( fscanf( pFile, "%s", pBuffer ) == 1 ) + char * pBuffer = Abc_UtilStrsavTwo( "\\", pToken ); + int RetValue = Abc_NamStrFindOrAdd( p, pBuffer, NULL ); + ABC_FREE( pBuffer ); + return RetValue; +} +void Wln_PrintGuidance( Vec_Wec_t * vGuide, Abc_Nam_t * p ) +{ + Vec_Int_t * vLevel; int i, k, Obj; + Vec_WecForEachLevel( vGuide, vLevel, i ) { - if ( pBuffer[(int)strlen(pBuffer)-1] == '\r' ) - pBuffer[(int)strlen(pBuffer)-1] = 0; - if ( !strcmp(pBuffer, "prove") && Vec_IntSize(vTokens) % 4 == 3 ) // account for "property" - Vec_IntPush( vTokens, -1 ); - if ( Vec_IntSize(vTokens) % 4 == 2 || Vec_IntSize(vTokens) % 4 == 3 ) - Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, Buffer, NULL) ); - else - Vec_IntPush( vTokens, Abc_NamStrFindOrAdd(p, pBuffer, NULL) ); + Vec_IntForEachEntry( vLevel, Obj, k ) + printf( "%s ", Obj >= 0 ? Abc_NamStr(p, Obj) : "[unknown]" ); + printf( "\n" ); + } +} +Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ) +{ + char * pBuffer = ABC_CALLOC( char, 10000 ), * pToken; + Vec_Wec_t * vTokens = Vec_WecAlloc( 100 ); Vec_Int_t * vLevel; + FILE * pFile = fopen( pFileName, "rb" ); + while ( fgets( pBuffer, 10000, pFile ) ) + { + if ( pBuffer[0] == '#' ) + continue; + vLevel = Vec_WecPushLevel( vTokens ); + pToken = strtok( pBuffer, " \t\r\n" ); + while ( pToken ) + { + Vec_IntPush( vLevel, Vec_IntSize(vLevel) < 2 ? Abc_NamStrFindOrAdd(p, pToken, NULL) : Wln_ReadFindToken(pToken, p) ); + pToken = strtok( NULL, " \t\r\n" ); + } + if ( Vec_IntSize(vLevel) % 4 == 3 ) // account for "property" + Vec_IntPush( vLevel, -1 ); + assert( Vec_IntSize(vLevel) % 4 == 0 ); } fclose( pFile ); - if ( Vec_IntSize(vTokens) % 4 == 3 ) // account for "property" - Vec_IntPush( vTokens, -1 ); - assert( Vec_IntSize(vTokens) % 4 == 0 ); + if ( Vec_WecSize(vTokens) == 0 ) + printf( "Guidance is empty.\n" ); + //Wln_PrintGuidance( vTokens, p ); + ABC_FREE( pBuffer ); return vTokens; } diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index bc4211acb..b4e5f0092 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -335,6 +335,39 @@ int Rtl_LibFindModule( Rtl_Lib_t * p, int NameId ) return i; return -1; } +int Rtl_LibFindModule2( Rtl_Lib_t * p, int NameId, int iNtk0 ) +{ + char * pName = Rtl_LibStr( p, NameId ); + Rtl_Ntk_t * pNtk0 = Rtl_LibNtk( p, iNtk0 ); + Rtl_Ntk_t * pNtk; int i; + int Counts0[4] = {0}; Rtl_NtkCountPio( pNtk0, Counts0 ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + if ( strstr(Rtl_NtkName(pNtk), pName+1) ) + { + int Counts[4] = {0}; Rtl_NtkCountPio( pNtk, Counts ); + if ( Counts[1] == Counts0[1] && Counts[3] == Counts0[3] ) + return i; + } + return -1; +} +int Rtl_LibFindTwoModules( Rtl_Lib_t * p, int Name1, int Name2 ) +{ + int iNtk1 = Rtl_LibFindModule( p, Name1 ); + if ( Name2 == -1 ) + return (iNtk1 << 16) | iNtk1; + else + { + int Counts1[4] = {0}, Counts2[4] = {0}; + int iNtk2 = Rtl_LibFindModule( p, Name2 ); + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); + Rtl_NtkCountPio( pNtk1, Counts1 ); + Rtl_NtkCountPio( pNtk2, Counts2 ); + if ( Counts1[1] != Counts2[1] || Counts1[3] != Counts2[3] ) + iNtk1 = Rtl_LibFindModule2( p, Name1, iNtk2 ); + return (iNtk1 << 16) | iNtk2; + } +} void Rtl_LibPrintStats( Rtl_Lib_t * p ) { Rtl_Ntk_t * pNtk; int i, nSymbs = 0; @@ -1404,7 +1437,7 @@ void Rtl_NtkUpdateBoxes( Rtl_Ntk_t * p ) Rtl_NtkForEachCell( p, pCell, i ) { Rtl_Ntk_t * pMod = Rtl_CellNtk( p, pCell ); - if ( pMod ) + if ( pMod && pMod->iCopy >= 0 ) pCell[2] = ABC_INFINITY + pMod->iCopy; } } @@ -2055,12 +2088,73 @@ printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rt Gia_ManPrintStats( p->pGia, NULL ); return p->pGia; } -void Rtl_LibBlast2( Rtl_Lib_t * pLib ) +void Rtl_LibMark_rec( Rtl_Ntk_t * pNtk ) { - Rtl_Ntk_t * p; int i; - Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, p, i ) - if ( p->pGia == NULL ) - p->pGia = Rtl_NtkBlast2( p ); + int i, * pCell; + if ( pNtk->iCopy == -1 ) + return; + Rtl_NtkForEachCell( pNtk, pCell, i ) + { + Rtl_Ntk_t * pMod = Rtl_CellNtk( pNtk, pCell ); + if ( pMod ) + Rtl_LibMark_rec( pMod ); + } + assert( pNtk->iCopy == -2 ); + pNtk->iCopy = -1; +} +void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots ) +{ + Rtl_Ntk_t * pNtk; int i, iNtk; + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) + pNtk->iCopy = -1; + if ( vRoots ) + { + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) + pNtk->iCopy = -2; + Vec_IntForEachEntry( vRoots, iNtk, i ) + Rtl_LibMark_rec( Rtl_LibNtk(pLib, iNtk) ); + } + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) + if ( pNtk->iCopy == -1 && pNtk->pGia == NULL ) + pNtk->pGia = Rtl_NtkBlast2( pNtk ); +// Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) +// if ( pNtk->iCopy == -2 ) +// printf( "Skipping network \"%s\" during bit-blasting.\n", Rtl_NtkName(pNtk) ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) + pNtk->iCopy = -1; +} +void Rtl_LibBlastClean( Rtl_Lib_t * p ) +{ + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + Gia_ManStopP( &pNtk->pGia ); +} +void Rtl_LibSetReplace( Rtl_Lib_t * p, Vec_Wec_t * vGuide ) +{ + Vec_Int_t * vLevel; int i, iNtk1, iNtk2; + Rtl_Ntk_t * pNtk, * pNtk1, * pNtk2; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->iCopy = -1; + Vec_WecForEachLevel( vGuide, vLevel, i ) + { + int Name1 = Vec_IntEntry( vLevel, 2 ); + int Name2 = Vec_IntEntry( vLevel, 3 ); + int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); + if ( iNtk == -1 ) + { + printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); + break; + } + iNtk1 = iNtk >> 16; + iNtk2 = iNtk & 0xFFFF; + pNtk1 = Rtl_LibNtk(p, iNtk1); + pNtk2 = Rtl_LibNtk(p, iNtk2); + pNtk1->iCopy = iNtk2; + if ( iNtk1 == iNtk2 ) + printf( "Preparing to prove \"%s\".\n", Rtl_NtkName(pNtk1) ); + else + printf( "Preparing to replace \"%s\" by \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); + } } @@ -2113,7 +2207,7 @@ finish: if ( p != p1 && p != p2 ) Gia_ManStopP( &p->pGia ); //Rtl_LibBlast( pLib ); - Rtl_LibBlast2( pLib ); + Rtl_LibBlast2( pLib, NULL ); } void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) { @@ -2185,24 +2279,61 @@ void Wln_SolveProperty( Rtl_Lib_t * p, int iNtk ) printf( "Proving property \"%s\".\n", Rtl_NtkName(pNtk) ); Rtl_LibSolve( p, pNtk ); } +Vec_Int_t * Wln_ReadNtkRoots( Rtl_Lib_t * p, Vec_Wec_t * vGuide ) +{ + Vec_Int_t * vLevel; int i; + Vec_Int_t * vRoots = Vec_IntAlloc( 100 ); + Vec_WecForEachLevel( vGuide, vLevel, i ) + { + int Name1 = Vec_IntEntry( vLevel, 2 ); + int Name2 = Vec_IntEntry( vLevel, 3 ); + int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); + if ( iNtk == -1 ) + { + printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); + break; + } +/* + else + { + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk >> 16 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk & 0xFFFF ); + printf( "Matching \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); + } +*/ + Vec_IntPushTwo( vRoots, iNtk >> 16, iNtk & 0xFFFF ); + } + return vRoots; +} void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ) { - extern Vec_Int_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ); - Vec_Int_t * vGuide = Wln_ReadGuidance( pFileName, p->pManName ); int i; + extern Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ); + Vec_Wec_t * vGuide = Wln_ReadGuidance( pFileName, p->pManName ); + Vec_Int_t * vRoots, * vLevel; int i, iNtk1, iNtk2; Vec_IntFillExtra( p->vMap, Abc_NamObjNumMax(p->pManName), -1 ); - Rtl_LibBlast2( p ); - for ( i = 0; i < Vec_IntSize(vGuide); i += 4 ) + Rtl_LibSetReplace( p, vGuide ); + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + vRoots = Wln_ReadNtkRoots( p, vGuide ); + Rtl_LibBlast2( p, vRoots ); + Vec_WecForEachLevel( vGuide, vLevel, i ) { - int Prove = Vec_IntEntry( vGuide, i+0 ); - int Type = Vec_IntEntry( vGuide, i+1 ); - int Name1 = Vec_IntEntry( vGuide, i+2 ); - int Name2 = Vec_IntEntry( vGuide, i+3 ); - int iNtk1 = Rtl_LibFindModule( p, Name1 ); - int iNtk2 = Name2 == -1 ? -1 : Rtl_LibFindModule( p, Name2 ); + int Prove = Vec_IntEntry( vLevel, 0 ); + int Type = Vec_IntEntry( vLevel, 1 ); + int Name1 = Vec_IntEntry( vLevel, 2 ); + int Name2 = Vec_IntEntry( vLevel, 3 ); + int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); + if ( iNtk == -1 ) + { + printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); + break; + } + iNtk1 = iNtk >> 16; + iNtk2 = iNtk & 0xFFFF; if ( Prove != Rtl_LibStrId(p, "prove") ) - printf( "Unknown task in line %d.\n", i/4 ); - else if ( iNtk1 == -1 ) - printf( "Network %s cannot be found in this design.\n", Rtl_LibStr(p, Name1) ); + printf( "Unknown task in line %d.\n", i ); + //else if ( iNtk1 == -1 ) + // printf( "Network %s cannot be found in this design.\n", Rtl_LibStr(p, Name1) ); else { if ( Type == Rtl_LibStrId(p, "equal") ) @@ -2215,7 +2346,9 @@ void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ) } break; } - Vec_IntFree( vGuide ); + Rtl_LibBlastClean( p ); + Vec_WecFree( vGuide ); + Vec_IntFree( vRoots ); } //////////////////////////////////////////////////////////////////////// From d86e8d9ed858d2ab081fe1ca5bfacdfb7aa28018 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 6 Mar 2022 00:09:35 -0800 Subject: [PATCH 36/74] Experiments with word-level data structures. --- src/base/wln/wlnRead.c | 101 +++++++++++++++++++++++++++++++++++++---- src/proof/cec/cec.h | 1 + src/proof/cec/cecCec.c | 15 ++++++ 3 files changed, 107 insertions(+), 10 deletions(-) diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index b4e5f0092..b42a47913 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -2137,6 +2137,7 @@ void Rtl_LibSetReplace( Rtl_Lib_t * p, Vec_Wec_t * vGuide ) pNtk->iCopy = -1; Vec_WecForEachLevel( vGuide, vLevel, i ) { + int Type = Vec_IntEntry( vLevel, 1 ); int Name1 = Vec_IntEntry( vLevel, 2 ); int Name2 = Vec_IntEntry( vLevel, 3 ); int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); @@ -2145,6 +2146,8 @@ void Rtl_LibSetReplace( Rtl_Lib_t * p, Vec_Wec_t * vGuide ) printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); break; } + if ( Type != Rtl_LibStrId(p, "equal") ) + continue; iNtk1 = iNtk >> 16; iNtk2 = iNtk & 0xFFFF; pNtk1 = Rtl_LibNtk(p, iNtk1); @@ -2215,9 +2218,9 @@ void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) abctime clk = Abc_Clock(); int Status; Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib ); Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pTop->pGia, 1000000, 0 ); - int RetValue = Gia_ManAndNum(pSwp) == 0; + int RetValue = Gia_ManAndNum(pSwp); Gia_ManStop( pSwp ); - if ( RetValue ) + if ( RetValue == 0 ) printf( "Verification problem solved after SAT sweeping! " ); else { @@ -2229,7 +2232,7 @@ void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) if ( Status == 1 ) printf( "Verification problem solved after CEC! " ); else - printf( "Verification problem is NOT solved! " ); + printf( "Verification problem is NOT solved (miter has %d nodes)! ", RetValue ); } Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } @@ -2248,35 +2251,113 @@ void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) ***********************************************************************/ void Wln_SolveEqual( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) { + abctime clk = Abc_Clock(); Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); - printf( "Proving equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); -/* + printf( "\nProving equivalence of \"%s\" and \"%s\"...\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); if ( Gia_ManCiNum(pNtk1->pGia) != Gia_ManCiNum(pNtk2->pGia) || Gia_ManCoNum(pNtk1->pGia) != Gia_ManCoNum(pNtk2->pGia) ) { printf( "The number of inputs/outputs does not match.\n" ); } + else if ( 1 ) + { + Gia_Man_t * pGia = Gia_ManMiter( pNtk1->pGia, pNtk2->pGia, 0, 0, 0, 0, 0 ); + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 ); + //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Gia_ManStopP( &pNew ); + Gia_ManStopP( &pGia ); + } else { int Status = Cec_ManVerifyTwo( pNtk1->pGia, pNtk2->pGia, 0 ); if ( Status == 1 ) - printf( "The networks are equivalence.\n" ); + printf( "The networks are equivalent. " ); else - printf( "The networks are NOT equivalent.\n" ); + printf( "The networks are NOT equivalent. " ); } -*/ + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} +int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts ) +{ + int i, * pWire, iFirst = -1, Counts[4] = {0}, nBits = 0; + assert( p->nOutputs == 1 ); + Rtl_NtkForEachWire( p, pWire, i ) + { + if ( pWire[0] & 1 ) // PI + Counts[0]++, Counts[1] += pWire[1]; + if ( pWire[0] & 2 ) // PO + Counts[2]++, Counts[3] += pWire[1]; + } + assert( p->nInputs == Counts[0] ); + assert( p->nOutputs == Counts[2] ); + *pnOuts = Counts[3]; + Rtl_NtkForEachWire( p, pWire, i ) + { + if ( pWire[0] & 1 ) // PI + { + if ( pWire[1] == Counts[3] ) + return nBits; + nBits += pWire[1]; + } + } + return -1; +} +Gia_Man_t * Gia_ManMoveSharedFirst( Gia_Man_t * pGia, int iFirst, int nBits ) +{ + Vec_Int_t * vPiPerm = Vec_IntAlloc( Gia_ManPiNum(pGia) ); + Gia_Man_t * pTemp; int i, n; + for ( n = 0; n < 2; n++ ) + for ( i = 0; i < Gia_ManPiNum(pGia); i++ ) + if ( n == (i >= iFirst && i < iFirst + nBits) ) + Vec_IntPush( vPiPerm, i ); + pTemp = Gia_ManDupPerm( pGia, vPiPerm ); + Vec_IntFree( vPiPerm ); + return pTemp; } void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) { + abctime clk = Abc_Clock(); Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); - printf( "Proving inverse equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); + int Res = printf( "\nProving inverse equivalence of \"%s\" and \"%s\".\n", Rtl_NtkName(pNtk1), Rtl_NtkName(pNtk2) ); + int nOuts1, iFirst1 = Gia_ManFindFirst( pNtk1, &nOuts1 ); + int nOuts2, iFirst2 = Gia_ManFindFirst( pNtk2, &nOuts2 ); + Gia_Man_t * pGia1 = Gia_ManMoveSharedFirst( pNtk1->pGia, iFirst1, nOuts1 ); + Gia_Man_t * pGia2 = Gia_ManMoveSharedFirst( pNtk2->pGia, iFirst2, nOuts2 ); + if ( 1 ) + { + Gia_Man_t * pGia = Gia_ManMiterInverse( pGia1, pGia2, 0, 0 ); + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 ); + //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Gia_ManStopP( &pNew ); + Gia_ManStopP( &pGia ); + } + else + { + int Status = Cec_ManVerifyTwoInv( pGia1, pGia2, 0 ); + if ( Status == 1 ) + printf( "The networks are equivalent. " ); + else + printf( "The networks are NOT equivalent. " ); + } + Res = 0; + Gia_ManStopP( &pGia1 ); + Gia_ManStopP( &pGia2 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } void Wln_SolveProperty( Rtl_Lib_t * p, int iNtk ) { Rtl_Ntk_t * pNtk = Rtl_LibNtk( p, iNtk ); - printf( "Proving property \"%s\".\n", Rtl_NtkName(pNtk) ); + printf( "\nProving property \"%s\".\n", Rtl_NtkName(pNtk) ); Rtl_LibSolve( p, pNtk ); } Vec_Int_t * Wln_ReadNtkRoots( Rtl_Lib_t * p, Vec_Wec_t * vGuide ) diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h index 7c101570c..40aa9799f 100644 --- a/src/proof/cec/cec.h +++ b/src/proof/cec/cec.h @@ -206,6 +206,7 @@ struct Cec_ParSeq_t_ /*=== cecCec.c ==========================================================*/ extern int Cec_ManVerify( Gia_Man_t * p, Cec_ParCec_t * pPars ); extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); +extern int Cec_ManVerifyTwoInv( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); extern int Cec_ManVerifySimple( Gia_Man_t * p ); /*=== cecChoice.c ==========================================================*/ extern Gia_Man_t * Cec_ManChoiceComputation( Gia_Man_t * pAig, Cec_ParChc_t * pPars ); diff --git a/src/proof/cec/cecCec.c b/src/proof/cec/cecCec.c index cfa07ff89..f6a1ab527 100644 --- a/src/proof/cec/cecCec.c +++ b/src/proof/cec/cecCec.c @@ -465,6 +465,21 @@ int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ) Gia_ManStop( pMiter ); return RetValue; } +int Cec_ManVerifyTwoInv( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ) +{ + Cec_ParCec_t ParsCec, * pPars = &ParsCec; + Gia_Man_t * pMiter; + int RetValue; + Cec_ManCecSetDefaultParams( pPars ); + pPars->fVerbose = fVerbose; + pMiter = Gia_ManMiterInverse( p0, p1, 1, pPars->fVerbose ); + if ( pMiter == NULL ) + return -1; + RetValue = Cec_ManVerify( pMiter, pPars ); + p0->pCexComb = pMiter->pCexComb; pMiter->pCexComb = NULL; + Gia_ManStop( pMiter ); + return RetValue; +} /**Function************************************************************* From ee228339e5e14b7a3651454814e91b80c3cb4b1e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 6 Mar 2022 00:10:52 -0800 Subject: [PATCH 37/74] Experiments with word-level data structures. --- src/base/wln/wlnRead.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index b42a47913..95d2dd314 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -154,11 +154,12 @@ static inline int Rtl_SigIsConcat( int s ) { ret #define Rtl_CellForEachOutput( p, pCell, Par, Val, i ) \ Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i < Rtl_CellInputNum(pCell) ) continue; else +extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// - /**Function************************************************************* Synopsis [] @@ -2214,7 +2215,6 @@ finish: } void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) { - extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); abctime clk = Abc_Clock(); int Status; Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib ); Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pTop->pGia, 1000000, 0 ); From 4f2cd590bce70fd5b52b5c92819a54d9294571d3 Mon Sep 17 00:00:00 2001 From: Stephen L Arnold Date: Sun, 27 Mar 2022 12:45:13 -0700 Subject: [PATCH 38/74] fix windows CI => project file integration broken on windows-latest * use windows-2019 until updated project files are usable on 2022 Signed-off-by: Stephen L Arnold --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 6312780d8..21cd1b26d 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -4,7 +4,7 @@ jobs: build-windows: - runs-on: windows-latest + runs-on: windows-2019 steps: From a24b15d03a87b897494330f0c11319abb129372d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 29 Mar 2022 15:31:13 -0700 Subject: [PATCH 39/74] Suggested changes for the case when the file begings with a new line. --- src/map/amap/amapRead.c | 66 ++++++++++++++++++++++++----------------- src/map/mio/mioRead.c | 61 +++++++++++++++++++++---------------- 2 files changed, 74 insertions(+), 53 deletions(-) diff --git a/src/map/amap/amapRead.c b/src/map/amap/amapRead.c index 3ccfc0115..9e6ee21c8 100644 --- a/src/map/amap/amapRead.c +++ b/src/map/amap/amapRead.c @@ -126,41 +126,52 @@ void Amap_RemoveComments( char * pBuffer, int * pnDots, int * pnLines ) // (in the BLIF file, comments are lines starting with "#") nDots = nLines = 0; for ( pCur = pBuffer; *pCur; pCur++ ) - { + { // if this is the beginning of comment // clean it with spaces until the new line statement - if ( *pCur == '#' ) - while ( *pCur != '\n' ) - *pCur++ = ' '; - + if ( *pCur == '#' ) { + while ( *pCur != '\n' ) { + *pCur++ = ' '; + } + } // count the number of new lines and dots if ( *pCur == '\n' ) { - if (*(pCur-1)=='\r') { - // DOS(R) file support - if (*(pCur-2)!='\\') nLines++; - else { - // rewind to backslash and overwrite with a space - *(pCur-2) = ' '; - *(pCur-1) = ' '; - *pCur = ' '; + if (pCur > pBuffer) { + if (*(pCur - 1) == '\r') { + // DOS(R) file support + if (pCur > (pBuffer + 1)) { + if (*(pCur - 2)!='\\') { + nLines++; + } + else { + // rewind to backslash and overwrite with a space + *(pCur - 2) = ' '; + *(pCur - 1) = ' '; + *pCur = ' '; + } + } + } else { + // UNIX(TM) file support + if (*(pCur - 1) != '\\') { + nLines++; + } + else { + // rewind to backslash and overwrite with a space + *(pCur-1) = ' '; + *pCur = ' '; + } + } + } } - } else { - // UNIX(TM) file support - if (*(pCur-1)!='\\') nLines++; - else { - // rewind to backslash and overwrite with a space - *(pCur-1) = ' '; - *pCur = ' '; + else if ( *pCur == '.' ) { + nDots++; } - } - } - else if ( *pCur == '.' ) - nDots++; - } + } + if ( pnDots ) - *pnDots = nDots; + *pnDots = nDots; if ( pnLines ) - *pnLines = nLines; + *pnLines = nLines; } /**Function************************************************************* @@ -491,4 +502,3 @@ Amap_Lib_t * Amap_LibReadFile( char * pFileName, int fVerbose ) ABC_NAMESPACE_IMPL_END - diff --git a/src/map/mio/mioRead.c b/src/map/mio/mioRead.c index c0a83cfdc..c19c07d4d 100644 --- a/src/map/mio/mioRead.c +++ b/src/map/mio/mioRead.c @@ -734,37 +734,48 @@ void Io_ReadFileRemoveComments( char * pBuffer, int * pnDots, int * pnLines ) // (in the BLIF file, comments are lines starting with "#") nDots = nLines = 0; for ( pCur = pBuffer; *pCur; pCur++ ) - { + { // if this is the beginning of comment // clean it with spaces until the new line statement - if ( *pCur == '#' ) - while ( *pCur != '\n' ) - *pCur++ = ' '; - + if ( *pCur == '#' ) { + while ( *pCur != '\n' ) { + *pCur++ = ' '; + } + } // count the number of new lines and dots if ( *pCur == '\n' ) { - if (*(pCur-1)=='\r') { - // DOS(R) file support - if (*(pCur-2)!='\\') nLines++; - else { - // rewind to backslash and overwrite with a space - *(pCur-2) = ' '; - *(pCur-1) = ' '; - *pCur = ' '; + if (pCur > pBuffer) { + if (*(pCur - 1) == '\r') { + // DOS(R) file support + if (pCur > (pBuffer + 1)) { + if (*(pCur - 2) != '\\') { + nLines++; + } + else { + // rewind to backslash and overwrite with a space + *(pCur - 2) = ' '; + *(pCur - 1) = ' '; + *pCur = ' '; + } + } + } else { + // UNIX(TM) file support + if (*(pCur - 1) != '\\') { + nLines++; + } + else { + // rewind to backslash and overwrite with a space + *(pCur - 1) = ' '; + *pCur = ' '; + } + } + } } - } else { - // UNIX(TM) file support - if (*(pCur-1)!='\\') nLines++; - else { - // rewind to backslash and overwrite with a space - *(pCur-1) = ' '; - *pCur = ' '; + else if ( *pCur == '.' ) { + nDots++; } - } - } - else if ( *pCur == '.' ) - nDots++; - } + } + if ( pnDots ) *pnDots = nDots; if ( pnLines ) From 5405003a5e99758988507cfb0f9ae4341c0025ff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 2 Apr 2022 23:44:57 -0700 Subject: [PATCH 40/74] Suggested changes to properly initialize the variable array for Cudd_bddVectorCompose(). --- src/base/abc/abcMinBase.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/base/abc/abcMinBase.c b/src/base/abc/abcMinBase.c index 991f65a43..92dbd0c98 100644 --- a/src/base/abc/abcMinBase.c +++ b/src/base/abc/abcMinBase.c @@ -113,7 +113,7 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) DdNode * bTemp, ** pbVars; Vec_Str_t * vSupport; int i, nVars, j, iFanin, iFanin2, k = 0; - int fDupFanins = 0; + int ddSize, fDupFanins = 0; assert( Abc_NtkIsBddLogic(pNode->pNtk) ); assert( Abc_ObjIsNode(pNode) ); @@ -127,8 +127,14 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) return 0; } - // remove unused fanins - pbVars = ABC_CALLOC( DdNode *, Abc_ObjFaninNum(pNode) ); + // remove unused fanins. + + // By default, every BDD variable stays equivalent to itself. + ddSize = Cudd_ReadSize( dd ); + pbVars = ABC_CALLOC( DdNode *, ddSize ); + for (i = 0; i < ddSize; i += 1 ) { + pbVars[i] = Cudd_bddIthVar( dd, i ); + } Vec_IntForEachEntry( &pNode->vFanins, iFanin, i ) { Abc_Obj_t * pFanin = Abc_NtkObj( pNode->pNtk, iFanin ); @@ -146,13 +152,18 @@ int Abc_NodeMinimumBase( Abc_Obj_t * pNode ) Vec_IntWriteEntry( &pNode->vFanins, k++, iFanin ); else if ( !Vec_IntRemove( &pFanin->vFanouts, pNode->Id ) ) printf( "The obj %d is not found among the fanouts of obj %d ...\n", pNode->Id, iFanin ); + + // i-th variable becomes equivalent to j-th variable (can be itself) pbVars[i] = Cudd_bddIthVar( dd, j ); } Vec_IntShrink( &pNode->vFanins, k ); // update the function of the node - pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars ); Cudd_Ref( (DdNode *)pNode->pData ); - Cudd_RecursiveDeref( dd, bTemp ); + if ( ! Cudd_IsConstant((DdNode *) pNode->pData ) ) { + pNode->pData = Cudd_bddVectorCompose( dd, bTemp = (DdNode *)pNode->pData, pbVars ); + Cudd_Ref( (DdNode *)pNode->pData ); + Cudd_RecursiveDeref( dd, bTemp ); + } Vec_StrFree( vSupport ); ABC_FREE( pbVars ); From 7ad8f9548c359f92cd40afcf715a948acc6b6326 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 4 Apr 2022 22:08:53 -0700 Subject: [PATCH 41/74] Experiments with word-level data structures. --- src/aig/gia/gia.h | 2 + src/aig/gia/giaDup.c | 90 +++++++++++++++++++++++-- src/base/abci/abc.c | 1 + src/base/abci/abcDar.c | 27 ++++++++ src/base/wln/wlnCom.c | 4 +- src/base/wln/wlnRead.c | 150 ++++++++++++++++++++++++++++++++++------- 6 files changed, 241 insertions(+), 33 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index d871905c8..488f12cfd 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1312,6 +1312,8 @@ extern Gia_Man_t * Gia_ManDupLastPis( Gia_Man_t * p, int nLastPis ); extern Gia_Man_t * Gia_ManDupFlip( Gia_Man_t * p, int * pInitState ); extern Gia_Man_t * Gia_ManDupCycled( Gia_Man_t * pAig, Abc_Cex_t * pCex, int nFrames ); extern Gia_Man_t * Gia_ManDup( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupNoBuf( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupMap( Gia_Man_t * p, Vec_Int_t * vMap ); extern Gia_Man_t * Gia_ManDup2( Gia_Man_t * p1, Gia_Man_t * p2 ); extern Gia_Man_t * Gia_ManDupWithAttributes( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupRemovePis( Gia_Man_t * p, int nRemPis ); diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 55f8901fd..4f094b48e 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -811,6 +811,55 @@ Gia_Man_t * Gia_ManDupRemovePis( Gia_Man_t * p, int nRemPis ) Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); return pNew; } +Gia_Man_t * Gia_ManDupNoBuf( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} +Gia_Man_t * Gia_ManDupMap( Gia_Man_t * p, Vec_Int_t * vMap ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Vec_IntEntry(vMap, i) >= 0 ) + pObj->Value = Gia_ManObj( p, Vec_IntEntry(vMap, i) )->Value; + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} /**Function************************************************************* @@ -865,7 +914,9 @@ Gia_Man_t * Gia_ManDupPerm( Gia_Man_t * p, Vec_Int_t * vPiPerm ) // Vec_IntFree( vPiPermInv ); Gia_ManForEachObj1( p, pObj, i ) { - if ( Gia_ObjIsAnd(pObj) ) + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsAnd(pObj) ) pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); else if ( Gia_ObjIsCi(pObj) ) { @@ -1086,7 +1137,7 @@ Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo ) Gia_ManSetRegNum( pNew, Gia_ManRegNum(pOne) + Gia_ManRegNum(pTwo) ); return pNew; } -void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ) +void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits, int fBufs ) { Gia_Obj_t * pObj; int i; assert( Vec_IntSize(vLits) == Gia_ManCiNum(p) ); @@ -1094,7 +1145,10 @@ void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ) Gia_ManForEachCi( p, pObj, i ) pObj->Value = Vec_IntEntry(vLits, i); Gia_ManForEachAnd( p, pObj, i ) - pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( fBufs && Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + else + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Vec_IntClear( vLits ); Gia_ManForEachCo( p, pObj, i ) Vec_IntPush( vLits, Gia_ObjFanin0Copy(pObj) ); @@ -2980,8 +3034,15 @@ Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOu Gia_ManHashAlloc( pNew ); Gia_ManForEachCi( pBot, pObj, i ) pObj->Value = Gia_ManAppendCi( pNew ); - Gia_ManForEachCo( pBot, pObj, i ) - Gia_ManMiter_rec( pNew, pBot, Gia_ObjFanin0(pObj) ); +// Gia_ManForEachCo( pBot, pObj, i ) +// Gia_ManMiter_rec( pNew, pBot, Gia_ObjFanin0(pObj) ); + Gia_ManForEachAnd( pBot, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } Gia_ManForEachCo( pBot, pObj, i ) pObj->Value = Gia_ObjFanin0Copy(pObj); Gia_ManForEachCi( pTop, pObj, i ) @@ -2989,8 +3050,15 @@ Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOu pObj->Value = Gia_ManCi(pBot, i)->Value; else pObj->Value = Gia_ManCo(pBot, i-nInputs1)->Value; - Gia_ManForEachCo( pTop, pObj, i ) - Gia_ManMiter_rec( pNew, pTop, Gia_ObjFanin0(pObj) ); +// Gia_ManForEachCo( pTop, pObj, i ) +// Gia_ManMiter_rec( pNew, pTop, Gia_ObjFanin0(pObj) ); + Gia_ManForEachAnd( pTop, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } Gia_ManForEachCo( pTop, pObj, i ) { if ( fDualOut ) @@ -3007,6 +3075,14 @@ Gia_Man_t * Gia_ManMiterInverse( Gia_Man_t * pBot, Gia_Man_t * pTop, int fDualOu Gia_ManHashStop( pNew ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); + assert( (pBot->vBarBufs == NULL) == (pTop->vBarBufs == NULL) ); + if ( pBot->vBarBufs ) + { + pNew->vBarBufs = Vec_IntAlloc( 1000 ); + Vec_IntAppend( pNew->vBarBufs, pBot->vBarBufs ); + Vec_IntAppend( pNew->vBarBufs, pTop->vBarBufs ); + //printf( "Miter has %d buffers (%d groups).\n", pNew->nBufs, Vec_IntSize(pNew->vBarBufs) ); + } return pNew; } diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 06d7cb081..db0446c99 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -13996,6 +13996,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) //Dau_NetworkEnumTest(); //Extra_SimulationTest( nDivMax, nNumOnes, fNewOrder ); //Mnist_ExperimentWithScaling( nDecMax ); + //Gyx_ProblemSolveTest(); return 0; usage: Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] \n" ); diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index f68180102..677cb7d08 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -658,6 +658,33 @@ Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia ) +{ + Aig_Man_t * pMan = Gia_ManToAig( pGia, 0 ); int Res; + Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan ), * pTemp; + //pNtk->pName = Extra_UtilStrsav(pGia->pName); + Aig_ManStop( pMan ); + // collapse the network + pNtk = Abc_NtkCollapse( pTemp = pNtk, 10000, 0, 1, 0, 0, 0 ); + Abc_NtkDelete( pTemp ); + if ( pNtk == NULL ) + return 0; + Res = Abc_NtkGetBddNodeNum( pNtk ); + Abc_NtkDelete( pNtk ); + return Res == 0; +} + /**Function************************************************************* diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index 90ac4faa8..a010c7c23 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -276,7 +276,7 @@ usage: int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Rtl_LibBlast( Rtl_Lib_t * pLib ); - extern void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots ); + extern void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots, int fInv ); extern void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ); extern void Rtl_LibPreprocess( Rtl_Lib_t * pLib ); extern void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ); @@ -327,7 +327,7 @@ int Abc_CommandSolve( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fOldBlast ) Rtl_LibBlast( pLib ); else - Rtl_LibBlast2( pLib, NULL ); + Rtl_LibBlast2( pLib, NULL, 0 ); if ( fPrepro ) Rtl_LibPreprocess( pLib ); Rtl_LibSolve( pLib, NULL ); diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 95d2dd314..43003075e 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -73,6 +73,7 @@ struct Rtl_Ntk_t_ int Slice0; // first slice int Slice1; // last slice int iCopy; // place in array + int fRoot; // denote root network }; static inline int Rtl_LibNtkNum( Rtl_Lib_t * pLib ) { return Vec_PtrSize(pLib->vNtks); } @@ -155,6 +156,7 @@ static inline int Rtl_SigIsConcat( int s ) { ret Rtl_CellForEachConnect( p, pCell, Par, Val, i ) if ( i < Rtl_CellInputNum(pCell) ) continue; else extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); +extern int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -1750,16 +1752,34 @@ void Rtl_NtkBlastConnect( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCon ) void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) { extern Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ); - extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits ); + extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits, int fBufs ); + extern int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts ); Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); + int nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 ); int k, Par, Val, nBits = 0; + //printf( "Blasting %s -> %s...\n", Rtl_NtkName(p), Rtl_NtkName(pModel) ); Vec_IntClear( &p->vBitTemp ); Rtl_CellForEachInput( p, pCell, Par, Val, k ) Rtl_NtkCollectSignalRange( p, Val ); // if ( pModel->pGia == NULL ) // pModel->pGia = Rtl_NtkBlast( pModel ); assert( pModel->pGia ); - Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp ); + if ( pModel->fRoot ) + { + Vec_IntForEachEntry( &p->vBitTemp, Val, k ) + Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); + Vec_IntPush( pNew->vBarBufs, Abc_Var2Lit(pModel->NameId, 0) ); + } + Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, !pModel->fRoot ); + if ( !pModel->fRoot ) + Vec_IntAppend( pNew->vBarBufs, pModel->pGia->vBarBufs ); + if ( pModel->fRoot ) + { + Vec_IntForEachEntry( &p->vBitTemp, Val, k ) + Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) ); + Vec_IntPush( pNew->vBarBufs, Abc_Var2Lit(pModel->NameId, 1) ); + printf( "Added %d and %d output buffers for module %s.\n", nOuts1, Vec_IntSize(&p->vBitTemp), Rtl_NtkName(pModel) ); + } Rtl_CellForEachOutput( p, pCell, Par, Val, k ) nBits += Rtl_NtkInsertSignalRange( p, Val, Vec_IntArray(&p->vBitTemp)+nBits, Vec_IntSize(&p->vBitTemp)-nBits ); assert( nBits == Vec_IntSize(&p->vBitTemp) ); @@ -1821,6 +1841,16 @@ char * Rtl_ShortenName( char * pName, int nSize ) Buffer[nSize-0] = 0; return Buffer; } +void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs ) +{ + int i, Lit; + if ( Vec_IntSize(vBufs) ) + printf( "Found %d buffers: ", p->pGia->nBufs ); + Vec_IntForEachEntry( vBufs, Lit, i ) + printf( "%s (%c) ", Rtl_LibStr(p->pLib, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit)? 'o' : 'i' ); + if ( Vec_IntSize(vBufs) ) + printf( "\n" ); +} Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) { Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); @@ -2068,6 +2098,7 @@ printf( "Blasting %s...\r", Rtl_NtkName(p) ); Rtl_NtkBlastMap( p, nBits ); assert( p->pGia == NULL ); p->pGia = Gia_ManStart( 1000 ); + p->pGia->vBarBufs = Vec_IntAlloc( 1000 ); Rtl_NtkBlastInputs( p->pGia, p ); Gia_ManHashAlloc( p->pGia ); for ( i = 0; i < p->nOutputs; i++ ) @@ -2081,7 +2112,10 @@ printf( "Blasting %s...\r", Rtl_NtkName(p) ); Rtl_NtkBlastOutputs( p->pGia, p ); Rtl_NtkMapWires( p, 1 ); p->pGia = Gia_ManCleanup( pTemp = p->pGia ); + ABC_SWAP( Vec_Int_t *, p->pGia->vBarBufs, pTemp->vBarBufs ); Gia_ManStop( pTemp ); +// if ( p->fRoot ) +// Rtl_NtkPrintBufs( p, p->pGia->vBarBufs ); sprintf( Buffer, "new%02d.aig", counter++ ); Gia_AigerWrite( p->pGia, Buffer, 0, 0, 0 ); @@ -2103,7 +2137,7 @@ void Rtl_LibMark_rec( Rtl_Ntk_t * pNtk ) assert( pNtk->iCopy == -2 ); pNtk->iCopy = -1; } -void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots ) +void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots, int fInv ) { Rtl_Ntk_t * pNtk; int i, iNtk; Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) @@ -2111,9 +2145,13 @@ void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots ) if ( vRoots ) { Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) - pNtk->iCopy = -2; + pNtk->iCopy = -2, pNtk->fRoot = 0; Vec_IntForEachEntry( vRoots, iNtk, i ) - Rtl_LibMark_rec( Rtl_LibNtk(pLib, iNtk) ); + { + Rtl_Ntk_t * pNtk = Rtl_LibNtk(pLib, iNtk); + pNtk->fRoot = fInv; + Rtl_LibMark_rec( pNtk ); + } } Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) if ( pNtk->iCopy == -1 && pNtk->pGia == NULL ) @@ -2211,15 +2249,18 @@ finish: if ( p != p1 && p != p2 ) Gia_ManStopP( &p->pGia ); //Rtl_LibBlast( pLib ); - Rtl_LibBlast2( pLib, NULL ); + Rtl_LibBlast2( pLib, NULL, 0 ); } void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) { + extern Gia_Man_t * Gia_ManReduceBuffers( Rtl_Lib_t * pLib, Gia_Man_t * p ); abctime clk = Abc_Clock(); int Status; - Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib ); - Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pTop->pGia, 1000000, 0 ); + Rtl_Ntk_t * pTop = pNtk ? (Rtl_Ntk_t *)pNtk : Rtl_LibTop( pLib ); + Gia_Man_t * pGia2 = Gia_ManReduceBuffers( pLib, pTop->pGia ); + Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pGia2, 1000000, 0 ); int RetValue = Gia_ManAndNum(pSwp); Gia_ManStop( pSwp ); + Gia_ManStop( pGia2 ); if ( RetValue == 0 ) printf( "Verification problem solved after SAT sweeping! " ); else @@ -2263,14 +2304,19 @@ void Wln_SolveEqual( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) else if ( 1 ) { Gia_Man_t * pGia = Gia_ManMiter( pNtk1->pGia, pNtk2->pGia, 0, 0, 0, 0, 0 ); - Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 ); - //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); - if ( Gia_ManAndNum(pNew) == 0 ) - Abc_Print( 1, "Networks are equivalent. " ); + if ( Abc_NtkFromGiaCollapse( pGia ) ) + Abc_Print( 1, "Networks are equivalent after collapsing. " ); else - Abc_Print( 1, "Networks are UNDECIDED. " ); - Gia_ManStopP( &pNew ); - Gia_ManStopP( &pGia ); + { + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 ); + //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Gia_ManStopP( &pNew ); + Gia_ManStopP( &pGia ); + } } else { @@ -2284,7 +2330,7 @@ void Wln_SolveEqual( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) } int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts ) { - int i, * pWire, iFirst = -1, Counts[4] = {0}, nBits = 0; + int i, * pWire, Counts[4] = {0}, nBits = 0; assert( p->nOutputs == 1 ); Rtl_NtkForEachWire( p, pWire, i ) { @@ -2316,9 +2362,49 @@ Gia_Man_t * Gia_ManMoveSharedFirst( Gia_Man_t * pGia, int iFirst, int nBits ) if ( n == (i >= iFirst && i < iFirst + nBits) ) Vec_IntPush( vPiPerm, i ); pTemp = Gia_ManDupPerm( pGia, vPiPerm ); + if ( pGia->vBarBufs ) + pTemp->vBarBufs = Vec_IntDup( pGia->vBarBufs ); Vec_IntFree( vPiPerm ); return pTemp; } +Vec_Int_t * Gia_ManCollectBufs( Gia_Man_t * p, int iFirst, int nBufs ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Gia_Obj_t * pObj; int i, iBuf = 0; + assert( iFirst >= 0 && iFirst + nBufs < p->nBufs ); + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) && iBuf >= iFirst && iBuf < iFirst + nBufs ) + Vec_IntPush( vRes, i ); + iBuf += Gia_ObjIsBuf(pObj); + } + assert( iBuf == p->nBufs ); + return vRes; +} +Gia_Man_t * Gia_ManReduceBuffers( Rtl_Lib_t * pLib, Gia_Man_t * p ) +{ + Gia_Man_t * pNew; + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vOne = Gia_ManCollectBufs( p, 0, 64 ); + Vec_Int_t * vTwo = Gia_ManCollectBufs( p, 1280-64, 64 ); + //Vec_Int_t * vOne = Gia_ManCollectBufs( p, 0, 1280/2 ); + //Vec_Int_t * vTwo = Gia_ManCollectBufs( p, 1280/2, 1280/2 ); + int i, One, Two; + printf( "Reducing %d buffers... Size(vOne) = %d. Size(vTwo) = %d. \n", p->nBufs, Vec_IntSize(vOne), Vec_IntSize(vTwo) ); + assert( p->nBufs == 1280 ); + Vec_IntForEachEntryTwo( vOne, vTwo, One, Two, i ) + Vec_IntWriteEntry( vMap, Two, One ); + Vec_IntFree( vOne ); + Vec_IntFree( vTwo ); +Gia_ManPrintStats( p, NULL ); + //pNew = Gia_ManDupNoBuf( p ); + pNew = Gia_ManDupMap( p, vMap ); +Gia_ManPrintStats( pNew, NULL ); + Vec_IntFree( vMap ); + //Rtl_NtkPrintBufs( pNtk1, pGia->vBarBufs ); + //printf( "Found %d buffers.\n", p->nBufs ); + return pNew; +} void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) { abctime clk = Abc_Clock(); @@ -2331,14 +2417,26 @@ void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) Gia_Man_t * pGia2 = Gia_ManMoveSharedFirst( pNtk2->pGia, iFirst2, nOuts2 ); if ( 1 ) { + char * pFileName = "inv_miter.aig"; Gia_Man_t * pGia = Gia_ManMiterInverse( pGia1, pGia2, 0, 0 ); - Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia, 10000000, 0 ); - //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); - if ( Gia_ManAndNum(pNew) == 0 ) - Abc_Print( 1, "Networks are equivalent. " ); + //Gia_Man_t * pGia2 = Gia_ManReduceBuffers( p, pGia ); + Gia_Man_t * pGia2 = Gia_ManDupNoBuf( pGia ); + printf( "Dumping inverse miter into file \"%s\".\n", pFileName ); + Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 ); + if ( Abc_NtkFromGiaCollapse( pGia2 ) ) + Abc_Print( 1, "Networks are equivalent after collapsing. " ); else - Abc_Print( 1, "Networks are UNDECIDED. " ); - Gia_ManStopP( &pNew ); + { + Gia_Man_t * pNew = Cec4_ManSimulateTest3( pGia2, 10000000, 0 ); + Rtl_NtkPrintBufs( pNtk1, pGia->vBarBufs ); + //printf( "Miter %d -> %d\n", Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Gia_ManStopP( &pNew ); + } + Gia_ManStopP( &pGia2 ); Gia_ManStopP( &pGia ); } else @@ -2358,6 +2456,7 @@ void Wln_SolveProperty( Rtl_Lib_t * p, int iNtk ) { Rtl_Ntk_t * pNtk = Rtl_LibNtk( p, iNtk ); printf( "\nProving property \"%s\".\n", Rtl_NtkName(pNtk) ); + Rtl_NtkPrintBufs( pNtk, pNtk->pGia->vBarBufs ); Rtl_LibSolve( p, pNtk ); } Vec_Int_t * Wln_ReadNtkRoots( Rtl_Lib_t * p, Vec_Wec_t * vGuide ) @@ -2390,13 +2489,16 @@ void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ) { extern Vec_Wec_t * Wln_ReadGuidance( char * pFileName, Abc_Nam_t * p ); Vec_Wec_t * vGuide = Wln_ReadGuidance( pFileName, p->pManName ); - Vec_Int_t * vRoots, * vLevel; int i, iNtk1, iNtk2; + Vec_Int_t * vRoots, * vLevel; int i, iNtk1, iNtk2, fInv = 0; + Vec_WecForEachLevel( vGuide, vLevel, i ) + if ( Vec_IntEntry( vLevel, 1 ) == Rtl_LibStrId(p, "inverse") ) + fInv = 1; Vec_IntFillExtra( p->vMap, Abc_NamObjNumMax(p->pManName), -1 ); Rtl_LibSetReplace( p, vGuide ); Rtl_LibUpdateBoxes( p ); Rtl_LibReorderModules( p ); vRoots = Wln_ReadNtkRoots( p, vGuide ); - Rtl_LibBlast2( p, vRoots ); + Rtl_LibBlast2( p, vRoots, fInv ); Vec_WecForEachLevel( vGuide, vLevel, i ) { int Prove = Vec_IntEntry( vLevel, 0 ); From e5e5e3545ba835d54386adf96419501c3c5d6dda Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 4 Apr 2022 22:12:58 -0700 Subject: [PATCH 42/74] Added a switch to &dfs to perform levelized ordering. --- src/base/abci/abc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index db0446c99..34f15cf2c 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -32624,9 +32624,10 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) int fNormal = 0; int fRevFans = 0; int fRevOuts = 0; + int fLeveled = 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "nfovh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "nfolvh" ) ) != EOF ) { switch ( c ) { @@ -32639,6 +32640,9 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'o': fRevOuts ^= 1; break; + case 'l': + fLeveled ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -32653,7 +32657,9 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Dfs(): There is no AIG.\n" ); return 1; } - if ( fNormal ) + if ( fLeveled ) + pTemp = Gia_ManDupLevelized( pAbc->pGia ); + else if ( fNormal ) pTemp = Gia_ManDupOrderAiger( pAbc->pGia ); else pTemp = Gia_ManDupOrderDfsReverse( pAbc->pGia, fRevFans, fRevOuts ); @@ -32661,12 +32667,13 @@ int Abc_CommandAbc9Dfs( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &dfs [-nfovh]\n" ); + Abc_Print( -2, "usage: &dfs [-nfolvh]\n" ); Abc_Print( -2, "\t orders objects in the DFS order\n" ); - Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" ); - Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" ); + Abc_Print( -2, "\t-n : toggle using normalized ordering [default = %s]\n", fNormal? "yes": "no" ); + Abc_Print( -2, "\t-f : toggle using reverse fanin traversal order [default = %s]\n", fRevFans? "yes": "no" ); Abc_Print( -2, "\t-o : toggle using reverse output traversal order [default = %s]\n", fRevOuts? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-l : toggle using levelized order [default = %s]\n", fLeveled? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } From b79f37ae57c891640240f1b5a39c70d58f75d8ac Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 22 Apr 2022 15:18:49 -0700 Subject: [PATCH 43/74] Experiments with word-level data structures. --- src/aig/gia/giaDup.c | 138 +++++++++++++++++++++++++++++++ src/aig/gia/giaSimBase.c | 73 ++++++++++++++++- src/base/abci/abc.c | 142 ++++++++++++++++++++++++++++++++ src/base/wln/wlnCom.c | 172 ++++++++++++++++++++++++++++++++++++++- src/base/wln/wlnRead.c | 152 ++++++++++++++++++++++++++++++++-- 5 files changed, 667 insertions(+), 10 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 4f094b48e..1164e16b4 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -5221,6 +5221,144 @@ Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti ) return pNew; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wec_t ** Gia_ManDupUifBuildMap( Gia_Man_t * p ) +{ + Vec_Wec_t ** pvMap = ABC_ALLOC( Vec_Wec_t *, 2 ); + Vec_Int_t * vBufs = Vec_IntAlloc( p->nBufs ); + Gia_Obj_t * pObj; int i, Item, j, k = 0; + pvMap[0] = Vec_WecAlloc(10); + pvMap[1] = Vec_WecAlloc(10); + Gia_ManForEachObj1( p, pObj, i ) + if ( Gia_ObjIsBuf(pObj) ) + Vec_IntPush( vBufs, i ); + assert( p->nBufs == Vec_IntSize(vBufs) ); + Vec_IntForEachEntry( p->vBarBufs, Item, i ) + { + Vec_Int_t * vVec = Vec_WecPushLevel(pvMap[Item&1]); + for ( j = 0; j < (Item >> 16); j++ ) + Vec_IntPush( vVec, Vec_IntEntry(vBufs, k++) ); + } + Vec_IntFree( vBufs ); + assert( p->nBufs == k ); + assert( Vec_WecSize(pvMap[0]) == Vec_WecSize(pvMap[1]) ); + return pvMap; +} +int Gia_ManDupUifConstrOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vVec0, Vec_Int_t * vVec1 ) +{ + Vec_Int_t * vTemp = Vec_IntAlloc( Vec_IntSize(vVec0) ); + int i, o0, o1, iRes; + Vec_IntForEachEntryTwo( vVec0, vVec1, o0, o1, i ) + Vec_IntPush( vTemp, Gia_ManHashXor(pNew, Gia_ManObj(p, o0)->Value, Abc_LitNot(Gia_ManObj(p, o1)->Value)) ); + iRes = Gia_ManHashAndMulti( pNew, vTemp ); + Vec_IntFree( vTemp ); + return iRes; +} +int Gia_ManDupUifConstr( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t ** pvMap ) +{ + int i, k, iUif = 1; + assert( Vec_WecSize(pvMap[0]) == Vec_WecSize(pvMap[1]) ); + for ( i = 0; i < Vec_WecSize(pvMap[0]); i++ ) + for ( k = i + 1; k < Vec_WecSize(pvMap[0]); k++ ) + { + int iCond1 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[0], i), Vec_WecEntry(pvMap[0], k) ); + int iCond2 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[1], i), Vec_WecEntry(pvMap[1], k) ); + int iRes = Gia_ManHashOr( pNew, Abc_LitNot(iCond1), iCond2 ); + iUif = Gia_ManHashAnd( pNew, iUif, iRes ); + } + return iUif; +} +Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p ) +{ + Vec_Wec_t ** pvMap = Gia_ManDupUifBuildMap( p ); + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; + int i, iUif = 0; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ObjFanin0Copy(pObj); + } + iUif = Gia_ManDupUifConstr( pNew, p, pvMap ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ManAppendAnd(pNew, pObj->Value, iUif) ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Vec_WecFree( pvMap[0] ); + Vec_WecFree( pvMap[1] ); + ABC_FREE( pvMap ); + if ( p->vBarBufs ) + pNew->vBarBufs = Vec_IntDup( p->vBarBufs ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_ManDupBlackBoxBuildMap( Gia_Man_t * p ) +{ + Vec_Int_t * vMap = Vec_IntAlloc( p->nBufs ); int i, Item; + Vec_IntForEachEntry( p->vBarBufs, Item, i ) + Vec_IntFillExtra( vMap, Vec_IntSize(vMap) + (Item >> 16), Item & 1 ); + assert( p->nBufs == Vec_IntSize(vMap) ); + return vMap; +} +Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p ) +{ + Vec_Int_t * vMap = Gia_ManDupBlackBoxBuildMap( p ); + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i, k = 0; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManHashAlloc( pNew ); + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Vec_IntEntry(vMap, k++) ? Gia_ManAppendCi(pNew) : Gia_ObjFanin0Copy(pObj); // out/in + else if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Vec_IntFree( vMap ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index c31064fe9..c8808532d 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -750,7 +750,7 @@ void Gia_ManSimProfile( Gia_Man_t * pGia ) Vec_Wrd_t * vSims = Gia_ManSimPatSim( pGia ); int nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia); int nC0s = 0, nC1s = 0, nUnique = Gia_ManSimPatHashPatterns( pGia, nWords, vSims, &nC0s, &nC1s ); - printf( "Simulating %d patterns leads to %d unique objects (%.2f %% out of %d), Const0 = %d. Const1 = %d.\n", + printf( "Simulating %d patterns leads to %d unique objects (%.2f %% out of %d). Const0 = %d. Const1 = %d.\n", 64*nWords, nUnique, 100.0*nUnique/Gia_ManCandNum(pGia), Gia_ManCandNum(pGia), nC0s, nC1s ); Vec_WrdFree( vSims ); } @@ -2700,6 +2700,77 @@ Vec_Ptr_t * Gia_ManPtrWrdReadBin( char * pFileName, int fVerbose ) return p; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManCompareSims( Gia_Man_t * pHie, Gia_Man_t * pFlat, int nWords, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Vec_Wrd_t * vSims = pFlat->vSimsPi = pHie->vSimsPi = Vec_WrdStartRandom( Gia_ManCiNum(pFlat) * nWords ); + Vec_Wrd_t * vSims0 = Gia_ManSimPatSim( pFlat ); + Vec_Wrd_t * vSims1 = Gia_ManSimPatSim( pHie ); + Gia_Obj_t * pObj; int * pSpot, * pSpot2, i, nC0s = 0, nC1s = 0, nUnique = 0, nFound[3] = {0}, nBoundary = 0, nMatched = 0; + Vec_Mem_t * vStore = Vec_MemAlloc( nWords, 12 ); // 2^12 N-word entries per page + pFlat->vSimsPi = NULL; + pHie->vSimsPi = NULL; + Vec_WrdFree( vSims ); + + printf( "Comparing two AIGs using %d simulation words.\n", nWords ); + printf( "Hierarchical: " ); Gia_ManPrintStats( pHie, NULL ); + printf( "Flat: " ); Gia_ManPrintStats( pFlat, NULL ); + + Vec_MemHashAlloc( vStore, 1 << 12 ); + Gia_ManForEachCand( pFlat, pObj, i ) + { + word * pSim = Vec_WrdEntryP(vSims0, i*nWords); + nC0s += Abc_TtIsConst0(pSim, nWords); + nC1s += Abc_TtIsConst1(pSim, nWords); + Vec_MemHashInsert( vStore, pSim ); + } + nUnique = Vec_MemEntryNum( vStore ); + printf( "Simulating %d patterns through the second (flat) AIG leads to %d unique objects (%.2f %% out of %d). Const0 = %d. Const1 = %d.\n", + 64*nWords, nUnique, 100.0*nUnique/Gia_ManCandNum(pFlat), Gia_ManCandNum(pFlat), nC0s, nC1s ); + + assert( Gia_ManCiNum(pFlat) == Gia_ManCiNum(pHie) ); + Gia_ManForEachCand( pHie, pObj, i ) + { + word * pSim = Vec_WrdEntryP(vSims1, i*nWords); + pSpot = Vec_MemHashLookup( vStore, pSim ); + Abc_TtNot( pSim, nWords ); + pSpot2 = Vec_MemHashLookup( vStore, pSim ); + Abc_TtNot( pSim, nWords ); + nBoundary += Gia_ObjIsBuf(pObj); + if ( *pSpot != -1 || *pSpot2 != -1 ) + { + nMatched++; + continue; + } + //Extra_PrintBinary( stdout, (unsigned *)pSim, 64*nWords ); printf("\n"); + nFound[1] += Gia_ObjIsBuf(pObj); + nFound[2]++; + //if ( Gia_ObjIsBuf(pObj) ) + // printf( "%d(%d) ", i, nBoundary-1 ); + } + Vec_MemHashFree( vStore ); + Vec_MemFree( vStore ); + Vec_WrdFree( vSims0 ); + Vec_WrdFree( vSims1 ); + + printf( "The first (hierarchical) AIG has %d (%.2f %%) matches, %d (%.2f %%) mismatches, including %d (%.2f %%) on the boundary. ", + nMatched, 100.0*nMatched /Abc_MaxInt(1, Gia_ManCandNum(pHie)), + nFound[2], 100.0*nFound[2]/Abc_MaxInt(1, Gia_ManCandNum(pHie)), + nFound[1], 100.0*nFound[1]/Abc_MaxInt(1, nBoundary) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 34f15cf2c..e54b831df 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -519,6 +519,8 @@ static int Abc_CommandAbc9Iso ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9IsoNpn ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9IsoSt ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Compare ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9RevEng ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Uif ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9CexInfo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cycle ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Cone ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1263,6 +1265,8 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&isonpn", Abc_CommandAbc9IsoNpn, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&isost", Abc_CommandAbc9IsoSt, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&compare", Abc_CommandAbc9Compare, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&reveng", Abc_CommandAbc9RevEng, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&uif", Abc_CommandAbc9Uif, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cexinfo", Abc_CommandAbc9CexInfo, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cycle", Abc_CommandAbc9Cycle, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&cone", Abc_CommandAbc9Cone, 0 ); @@ -43713,6 +43717,144 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9RevEng( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManCompareSims( Gia_Man_t * pHie, Gia_Man_t * pFlat, int nWords, int fVerbose ); + Gia_Man_t * pGia0, * pGia1; + char ** pArgvNew; int nArgcNew; + int c, nWords = 4, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Wvh" ) ) != EOF ) + { + switch ( c ) + { + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); + goto usage; + } + nWords = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nWords < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9RevEng(): There is no AIG.\n" ); + return 1; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 1 ) + { + Abc_Print( -1, "Abc_CommandAbc9RevEng(): This command expects one AIG file name on the command line.\n" ); + return 1; + } + pGia0 = pAbc->pGia; + pGia1 = Gia_AigerRead( pArgvNew[0], 0, 0, 0 ); + if ( pGia0 == NULL || pGia1 == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9RevEng(): Reading input files did not work.\n" ); + return 1; + } + Gia_ManCompareSims( pGia0, pGia1, nWords, fVerbose ); + Gia_ManStop( pGia1 ); + return 0; + +usage: + Abc_Print( -2, "usage: &reveng [-W num] [-vh] \n" ); + Abc_Print( -2, "\t compares two AIGs for structural similarity\n" ); + Abc_Print( -2, "\t the current AIG is expected to contain some hierarchy\n" ); + Abc_Print( -2, "\t the given AIG from is expected to be flat\n" ); + Abc_Print( -2, "\t-W num : the number of 64-bit words of simulation info [default = %d]\n", nWords ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Uif( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p ); + extern Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p ); + Gia_Man_t * pNew = NULL, * pTemp = NULL; + int c, fBlackBox = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "bvh" ) ) != EOF ) + { + switch ( c ) + { + case 'b': + fBlackBox ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Uif(): There is no AIG.\n" ); + return 1; + } + if ( pAbc->pGia->vBarBufs == NULL || Vec_IntSize(pAbc->pGia->vBarBufs) == 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9Uif(): Hierarchy is not defined.\n" ); + return 1; + } + pNew = Gia_ManDupUif( pAbc->pGia ); + if ( fBlackBox ) + { + pNew = Gia_ManDupBlackBox( pTemp = pNew ); + Gia_ManStop( pTemp ); + } + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; + +usage: + Abc_Print( -2, "usage: &uif [-bvh]\n" ); + Abc_Print( -2, "\t eagerly adds UIF constraints when hierarchy is present\n" ); + Abc_Print( -2, "\t-b : toggle blackboxing while adding constraints [default = %s]\n", fBlackBox? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index a010c7c23..dcf12229e 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -28,6 +28,9 @@ ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// static int Abc_CommandYosys ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandGraft ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandHierarchy ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandCollapse ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSolve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPrint ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -53,7 +56,10 @@ static inline void Wln_AbcUpdateRtl( Abc_Frame_t * pAbc, Rtl_Lib_t * pLib void Wln_Init( Abc_Frame_t * pAbc ) { Cmd_CommandAdd( pAbc, "Word level", "%yosys", Abc_CommandYosys, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%hierarchy", Abc_CommandHierarchy, 0 ); + Cmd_CommandAdd( pAbc, "Word level", "%collapse", Abc_CommandCollapse, 0 ); + //Cmd_CommandAdd( pAbc, "Word level", "%solve", Abc_CommandSolve, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%print", Abc_CommandPrint, 0 ); } @@ -202,6 +208,170 @@ usage: return 1; } +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fVerbose ); + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + char ** pArgvNew; int nArgcNew; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pLib == NULL ) + { + printf( "The design is not entered.\n" ); + return 1; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 2 ) + { + Abc_Print( -1, "Abc_CommandGraft(): This command expects one AIG file name on the command line.\n" ); + return 1; + } + Wln_LibGraftOne( pLib, pArgvNew[0], pArgvNew[1], fVerbose ); + return 0; +usage: + Abc_Print( -2, "usage: %%graft [-vh] \n" ); + Abc_Print( -2, "\t replace instances of module1 by those of module2\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandHierarchy( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Wln_LibMarkHierarchy( Rtl_Lib_t * p, char ** ppModule, int nModules, int fVerbose ); + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + char ** pArgvNew; int nArgcNew; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pLib == NULL ) + { + printf( "The design is not entered.\n" ); + return 1; + } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew < 1 ) + { + Abc_Print( -1, "Abc_CommandHierarchy(): This command expects one AIG file name on the command line.\n" ); + return 1; + } + Wln_LibMarkHierarchy( pLib, pArgvNew, nArgcNew, fVerbose ); + return 0; +usage: + Abc_Print( -2, "usage: %%hierarchy [-vh] \n" ); + Abc_Print( -2, "\t marks the module whose instances may later be treated as black boxes\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function******************************************************************** + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +******************************************************************************/ +int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ); + Gia_Man_t * pNew = NULL; + Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); + char * pTopModule = NULL; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Tvh" ) ) != EOF ) + { + switch ( c ) + { + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by a file name.\n" ); + goto usage; + } + pTopModule = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pLib == NULL ) + { + printf( "The design is not entered.\n" ); + return 1; + } + pNew = Rtl_LibCollapse( pLib, pTopModule, fVerbose ); + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; +usage: + Abc_Print( -2, "usage: %%collapse [-T ] [-vh] \n" ); + Abc_Print( -2, "\t collapse hierarchical design into an AIG\n" ); + Abc_Print( -2, "\t-T : specify the top module of the design [default = none]\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [] diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 43003075e..8cd4af0cd 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -157,6 +157,7 @@ static inline int Rtl_SigIsConcat( int s ) { ret extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); extern int Abc_NtkFromGiaCollapse( Gia_Man_t * pGia ); +extern int Wln_ReadFindToken( char * pToken, Abc_Nam_t * p ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -1434,6 +1435,18 @@ void Rtl_LibReorderModules_rec( Rtl_Ntk_t * p, Vec_Ptr_t * vNew ) p->iCopy = Vec_PtrSize(vNew); Vec_PtrPush( vNew, p ); } +int Rtl_LibCountInsts( Rtl_Lib_t * p, Rtl_Ntk_t * pOne ) +{ + Rtl_Ntk_t * pNtk; int n, i, * pCell, Count = 0; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, n ) + Rtl_NtkForEachCell( pNtk, pCell, i ) + { + Rtl_Ntk_t * pMod = Rtl_CellNtk( pNtk, pCell ); + if ( pMod && pMod == pOne ) + Count++; + } + return Count; +} void Rtl_NtkUpdateBoxes( Rtl_Ntk_t * p ) { int i, * pCell; @@ -1755,7 +1768,7 @@ void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits, int fBufs ); extern int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts ); Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); - int nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 ); + int nIns = 0, nOuts = 0, nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 ); int k, Par, Val, nBits = 0; //printf( "Blasting %s -> %s...\n", Rtl_NtkName(p), Rtl_NtkName(pModel) ); Vec_IntClear( &p->vBitTemp ); @@ -1766,19 +1779,22 @@ void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) assert( pModel->pGia ); if ( pModel->fRoot ) { + nIns = Vec_IntSize(&p->vBitTemp); Vec_IntForEachEntry( &p->vBitTemp, Val, k ) - Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); - Vec_IntPush( pNew->vBarBufs, Abc_Var2Lit(pModel->NameId, 0) ); + //Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); + Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) ); + Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) ); } Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, !pModel->fRoot ); if ( !pModel->fRoot ) Vec_IntAppend( pNew->vBarBufs, pModel->pGia->vBarBufs ); if ( pModel->fRoot ) { + nOuts = Vec_IntSize(&p->vBitTemp); Vec_IntForEachEntry( &p->vBitTemp, Val, k ) Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) ); - Vec_IntPush( pNew->vBarBufs, Abc_Var2Lit(pModel->NameId, 1) ); - printf( "Added %d and %d output buffers for module %s.\n", nOuts1, Vec_IntSize(&p->vBitTemp), Rtl_NtkName(pModel) ); + Vec_IntPush( pNew->vBarBufs, (nOuts << 16) | Abc_Var2Lit(pModel->NameId, 1) ); + printf( "Added %d input buffers and %d output buffers for module %s.\n", nIns, nOuts, Rtl_NtkName(pModel) ); } Rtl_CellForEachOutput( p, pCell, Par, Val, k ) nBits += Rtl_NtkInsertSignalRange( p, Val, Vec_IntArray(&p->vBitTemp)+nBits, Vec_IntSize(&p->vBitTemp)-nBits ); @@ -1847,7 +1863,7 @@ void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs ) if ( Vec_IntSize(vBufs) ) printf( "Found %d buffers: ", p->pGia->nBufs ); Vec_IntForEachEntry( vBufs, Lit, i ) - printf( "%s (%c) ", Rtl_LibStr(p->pLib, Abc_Lit2Var(Lit)), Abc_LitIsCompl(Lit)? 'o' : 'i' ); + printf( "%s (%c%d) ", Rtl_LibStr(p->pLib, Abc_Lit2Var(Lit&0xFFFF)), Abc_LitIsCompl(Lit)? 'o' : 'i', Lit >> 16 ); if ( Vec_IntSize(vBufs) ) printf( "\n" ); } @@ -2145,11 +2161,11 @@ void Rtl_LibBlast2( Rtl_Lib_t * pLib, Vec_Int_t * vRoots, int fInv ) if ( vRoots ) { Vec_PtrForEachEntry( Rtl_Ntk_t *, pLib->vNtks, pNtk, i ) - pNtk->iCopy = -2, pNtk->fRoot = 0; + pNtk->iCopy = -2;//, pNtk->fRoot = 0; Vec_IntForEachEntry( vRoots, iNtk, i ) { Rtl_Ntk_t * pNtk = Rtl_LibNtk(pLib, iNtk); - pNtk->fRoot = fInv; + //pNtk->fRoot = fInv; Rtl_LibMark_rec( pNtk ); } } @@ -2259,6 +2275,9 @@ void Rtl_LibSolve( Rtl_Lib_t * pLib, void * pNtk ) Gia_Man_t * pGia2 = Gia_ManReduceBuffers( pLib, pTop->pGia ); Gia_Man_t * pSwp = Cec4_ManSimulateTest3( pGia2, 1000000, 0 ); int RetValue = Gia_ManAndNum(pSwp); + char * pFileName = "miter_to_solve.aig"; + printf( "Dumped the miter into file \"%s\".\n", pFileName ); + Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 ); Gia_ManStop( pSwp ); Gia_ManStop( pGia2 ); if ( RetValue == 0 ) @@ -2423,6 +2442,7 @@ void Wln_SolveInverse( Rtl_Lib_t * p, int iNtk1, int iNtk2 ) Gia_Man_t * pGia2 = Gia_ManDupNoBuf( pGia ); printf( "Dumping inverse miter into file \"%s\".\n", pFileName ); Gia_AigerWrite( pGia2, pFileName, 0, 0, 0 ); + printf( "Dumped the miter into file \"%s\".\n", pFileName ); if ( Abc_NtkFromGiaCollapse( pGia2 ) ) Abc_Print( 1, "Networks are equivalent after collapsing. " ); else @@ -2534,6 +2554,122 @@ void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ) Vec_IntFree( vRoots ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Rtl_LibReturnNtk( Rtl_Lib_t * p, char * pModule ) +{ + int NameId = Wln_ReadFindToken( pModule, p->pManName ); + int iNtk = NameId ? Rtl_LibFindModule( p, NameId ) : -1; + if ( iNtk == -1 ) + { + printf( "Cannot find module \"%s\" in the current design.\n", pModule ); + return -1; + } + return iNtk; +} +Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ) +{ + Gia_Man_t * pGia = NULL; + int NameId = Wln_ReadFindToken( pTopModule, p->pManName ); + int iNtk = NameId ? Rtl_LibFindModule( p, NameId ) : -1; + if ( iNtk == -1 ) + { + printf( "Cannot find top module \"%s\".\n", pTopModule ); + return NULL; + } + else + { + abctime clk = Abc_Clock(); + Rtl_Ntk_t * pTop = Rtl_LibNtk(p, iNtk); + Vec_Int_t * vRoots = Vec_IntAlloc( 1 ); + Vec_IntPush( vRoots, iNtk ); + Rtl_LibBlast2( p, vRoots, 1 ); + pGia = Gia_ManDup( pTop->pGia ); + if ( pTop->pGia->vBarBufs ) + pGia->vBarBufs = Vec_IntDup( pTop->pGia->vBarBufs ); + printf( "Finished computing global AIG for the top module \"%s\". ", Rtl_NtkStr(pTop, NameId) ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Rtl_NtkPrintBufs( pTop, pGia->vBarBufs ); + Rtl_LibBlastClean( p ); + Vec_IntFree( vRoots ); + } + return pGia; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fVerbose ) +{ + int Name1 = Wln_ReadFindToken( pModule1, p->pManName ); + int Name2 = Wln_ReadFindToken( pModule2, p->pManName ); + int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); + if ( iNtk == -1 ) + { + printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); + return; + } + else + { + int iNtk1 = iNtk >> 16; + int iNtk2 = iNtk & 0xFFFF; + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk(p, iNtk1); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk(p, iNtk2); + assert( iNtk1 != iNtk2 ); + printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + pNtk1->iCopy = iNtk2; + // Rtl_LibSetReplace( p, vGuide ); + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wln_LibMarkHierarchy( Rtl_Lib_t * p, char ** ppModule, int nModules, int fVerbose ) +{ + Rtl_Ntk_t * pNtk; int i; + if ( nModules == 0 ) // clean labels + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->fRoot = 0; + for ( i = 0; i < nModules; i++ ) + { + int iNtk = Rtl_LibReturnNtk( p, ppModule[i] ); + if ( iNtk == -1 ) + continue; + pNtk = Rtl_LibNtk( p, iNtk ); + pNtk->fRoot = 1; + printf( "Marking module \"%s\" (appearing %d times in the hierarchy).\n", ppModule[i], Rtl_LibCountInsts(p, pNtk) ); + } +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 8e13245ed06099734d10942715488ff2dc5b3186 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 08:53:57 -0700 Subject: [PATCH 44/74] Adding switch to stop scorr if refinement is too slow. --- src/base/abci/abc.c | 73 ++++++++++++++++++++++++++++++++++------- src/base/abci/abcDar.c | 3 +- src/proof/cec/cec.h | 1 + src/proof/cec/cecCorr.c | 36 ++++++++++++++++++-- src/proof/ssw/ssw.h | 1 + src/proof/ssw/sswCore.c | 25 ++++++++++++-- 6 files changed, 121 insertions(+), 18 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index e54b831df..9813fc1e0 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -21552,15 +21552,14 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk, * pNtkRes; Ssw_Pars_t Pars, * pPars = &Pars; - int nConstrs = 0; - int c; + int c, nConstrs = 0; extern Abc_Ntk_t * Abc_NtkDarSeqSweep2( Abc_Ntk_t * pNtk, Ssw_Pars_t * pPars ); pNtk = Abc_FrameReadNtk(pAbc); // set defaults Ssw_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNcmplkodsefqvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLSIVMNXcmplkodsefqvwh" ) ) != EOF ) { switch ( c ) { @@ -21674,6 +21673,17 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nConstrs < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLimitMax < 0 ) + goto usage; + break; case 'c': pPars->fConstrs ^= 1; break; @@ -21795,7 +21805,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: scorr [-PQFCLSIVMN ] [-cmplkodsefqvwh]\n" ); + Abc_Print( -2, "usage: scorr [-PQFCLSIVMNX ] [-cmplkodsefqvwh]\n" ); Abc_Print( -2, "\t performs sequential sweep using K-step induction\n" ); Abc_Print( -2, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize ); Abc_Print( -2, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize ); @@ -21808,6 +21818,7 @@ usage: Abc_Print( -2, "\t-V num : min var num needed to recycle the SAT solver [default = %d]\n", pPars->nSatVarMax2 ); Abc_Print( -2, "\t-M num : min call num needed to recycle the SAT solver [default = %d]\n", pPars->nRecycleCalls2 ); Abc_Print( -2, "\t-N num : set last POs to be constraints (use with -c) [default = %d]\n", nConstrs ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); Abc_Print( -2, "\t-c : toggle using explicit constraints [default = %s]\n", pPars->fConstrs? "yes": "no" ); Abc_Print( -2, "\t-m : toggle full merge if constraints are present [default = %s]\n", pPars->fMergeFull? "yes": "no" ); Abc_Print( -2, "\t-p : toggle aligning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" ); @@ -22118,10 +22129,11 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) int nFramesP; int nConfMax; int nVarsMax; + int nLimitMax; int fNewAlgor; int fVerbose; extern Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose ); - extern Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int fVerbose ); + extern Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int nLimitMax, int fVerbose ); pNtk = Abc_FrameReadNtk(pAbc); @@ -22131,10 +22143,11 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) nFramesP = 0; nConfMax = 1000; nVarsMax = 1000; + nLimitMax = 0; fNewAlgor = 1; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "PCSnvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "PCSXnvh" ) ) != EOF ) { switch ( c ) { @@ -22171,6 +22184,17 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nVarsMax < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLimitMax < 0 ) + goto usage; + break; case 'n': fNewAlgor ^= 1; break; @@ -22204,7 +22228,7 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) // get the new network if ( fNewAlgor ) - pNtkRes = Abc_NtkDarLcorrNew( pNtk, nVarsMax, nConfMax, fVerbose ); + pNtkRes = Abc_NtkDarLcorrNew( pNtk, nVarsMax, nConfMax, nLimitMax, fVerbose ); else pNtkRes = Abc_NtkDarLcorr( pNtk, nFramesP, nConfMax, fVerbose ); if ( pNtkRes == NULL ) @@ -22217,11 +22241,12 @@ int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: lcorr [-PCS num] [-nvh]\n" ); + Abc_Print( -2, "usage: lcorr [-PCSX num] [-nvh]\n" ); Abc_Print( -2, "\t computes latch correspondence using 1-step induction\n" ); Abc_Print( -2, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP ); Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfMax ); Abc_Print( -2, "\t-S num : the max number of SAT variables [default = %d]\n", nVarsMax ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", nLimitMax ); Abc_Print( -2, "\t-n : toggle using new algorithm [default = %s]\n", fNewAlgor? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); @@ -36411,7 +36436,7 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) Cec_ManCorSetDefaultParams( pPars ); pPars->fLatchCorr = 1; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FCPrcvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXrcvwh" ) ) != EOF ) { switch ( c ) { @@ -36448,6 +36473,17 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nPrefix < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLimitMax < 0 ) + goto usage; + break; case 'r': pPars->fUseRings ^= 1; break; @@ -36490,11 +36526,12 @@ int Abc_CommandAbc9Lcorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &lcorr [-FCP num] [-rcvwh]\n" ); + Abc_Print( -2, "usage: &lcorr [-FCPX num] [-rcvwh]\n" ); Abc_Print( -2, "\t performs latch correpondence computation\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" ); Abc_Print( -2, "\t-c : toggle using circuit-based SAT solver [default = %s]\n", pPars->fUseCSat? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); @@ -36523,7 +36560,7 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; Cec_ManCorSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "FCPpkrecqwvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "FCPXpkrecqwvh" ) ) != EOF ) { switch ( c ) { @@ -36560,6 +36597,17 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pPars->nPrefix < 0 ) goto usage; break; + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by an integer.\n" ); + goto usage; + } + pPars->nLimitMax = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( pPars->nLimitMax < 0 ) + goto usage; + break; case 'p': fPartition ^= 1; break; @@ -36617,11 +36665,12 @@ int Abc_CommandAbc9Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &scorr [-FCP num] [-pkrecqwvh]\n" ); + Abc_Print( -2, "usage: &scorr [-FCPX num] [-pkrecqwvh]\n" ); Abc_Print( -2, "\t performs signal correpondence computation\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-F num : the number of timeframes in inductive case [default = %d]\n", pPars->nFrames ); Abc_Print( -2, "\t-P num : the number of timeframes in the prefix [default = %d]\n", pPars->nPrefix ); + Abc_Print( -2, "\t-X num : the number of iterations of little or no improvement [default = %d]\n", pPars->nLimitMax ); Abc_Print( -2, "\t-p : toggle using partitioning for the input AIG [default = %s]\n", fPartition? "yes": "no" ); Abc_Print( -2, "\t-k : toggle using constant correspondence [default = %s]\n", pPars->fConstCorr? "yes": "no" ); Abc_Print( -2, "\t-r : toggle using implication rings during refinement [default = %s]\n", pPars->fUseRings? "yes": "no" ); diff --git a/src/base/abci/abcDar.c b/src/base/abci/abcDar.c index 677cb7d08..76c7cf547 100644 --- a/src/base/abci/abcDar.c +++ b/src/base/abci/abcDar.c @@ -2302,7 +2302,7 @@ Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int f SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int fVerbose ) +Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, int nLimitMax, int fVerbose ) { Ssw_Pars_t Pars, * pPars = &Pars; Aig_Man_t * pMan, * pTemp; @@ -2314,6 +2314,7 @@ Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, in pPars->fLatchCorrOpt = 1; pPars->nBTLimit = nConfMax; pPars->nSatVarMax = nVarsMax; + pPars->nLimitMax = nLimitMax; pPars->fVerbose = fVerbose; pMan = Ssw_SignalCorrespondence( pTemp = pMan, pPars ); Aig_ManStop( pTemp ); diff --git a/src/proof/cec/cec.h b/src/proof/cec/cec.h index 40aa9799f..92a08b3ef 100644 --- a/src/proof/cec/cec.h +++ b/src/proof/cec/cec.h @@ -149,6 +149,7 @@ struct Cec_ParCor_t_ int nBTLimit; // conflict limit at a node int nLevelMax; // (scorr only) the max number of levels int nStepsMax; // (scorr only) the max number of induction steps + int nLimitMax; // (scorr only) stop after this many iterations if little or no improvement int fLatchCorr; // consider only latch outputs int fConstCorr; // consider only constants int fUseRings; // use rings diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c index ce7e08850..8614ab072 100644 --- a/src/proof/cec/cecCorr.c +++ b/src/proof/cec/cecCorr.c @@ -756,6 +756,21 @@ void Cec_ManRefinedClassPrintStats( Gia_Man_t * p, Vec_Str_t * vStatus, int iIte Abc_Print( 1, "%c ", Gia_ObjIsConst( p, Gia_ObjFaninId0p(p, Gia_ManPo(p, 0)) ) ? '+' : '-' ); Abc_PrintTime( 1, "T", Time ); } +int Cec_ManCountLits( Gia_Man_t * p ) +{ + int i, CounterX = 0, Counter0 = 0, Counter = 0; + for ( i = 1; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjIsNone(p, i) ) + CounterX++; + else if ( Gia_ObjIsConst(p, i) ) + Counter0++; + else if ( Gia_ObjIsHead(p, i) ) + Counter++; + } + CounterX -= Gia_ManCoNum(p); + return Gia_ManCiNum(p) + Gia_ManAndNum(p) - Counter - CounterX; +} /**Function************************************************************* @@ -777,7 +792,7 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr Vec_Int_t * vCexStore; Cec_ManSim_t * pSim; Gia_Man_t * pSrm; - int fChanges, RetValue; + int fChanges, RetValue, i; // prepare simulation manager Cec_ManSimSetDefaultParams( pParsSim ); pParsSim->nWords = pPars->nWords; @@ -791,7 +806,7 @@ void Cec_ManLSCorrespondenceBmc( Gia_Man_t * pAig, Cec_ParCor_t * pPars, int nPr pParsSat->nBTLimit = pPars->nBTLimit; pParsSat->fVerbose = pPars->fVerbose; fChanges = 1; - while ( fChanges ) + for ( i = 0; fChanges && (!pPars->nLimitMax || i < pPars->nLimitMax); i++ ) { abctime clkBmc = Abc_Clock(); fChanges = 0; @@ -918,7 +933,7 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) Cec_ParSat_t ParsSat, * pParsSat = &ParsSat; Cec_ManSim_t * pSim; Gia_Man_t * pSrm; - int r, RetValue; + int r, RetValue, nPrev[4] = {0}; abctime clkTotal = Abc_Clock(); abctime clkSat = 0, clkSim = 0, clkSrm = 0; abctime clk2, clk = Abc_Clock(); @@ -1031,6 +1046,21 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) Cec_ManSimStop( pSim ); return 0; } + if ( pPars->nLimitMax ) + { + int nCur = Cec_ManCountLits(pAig); + if ( r > 4 && nPrev[0] - nCur <= 4*pPars->nLimitMax ) + { + printf( "Iterative refinement is stopped after iteration %d\n", r ); + printf( "because refinement does not proceed quickly.\n" ); + Cec_ManSimStop( pSim ); + return 0; + } + nPrev[0] = nPrev[1]; + nPrev[1] = nPrev[2]; + nPrev[2] = nPrev[3]; + nPrev[3] = nCur; + } } if ( pPars->fVerbose ) Cec_ManRefinedClassPrintStats( pAig, NULL, r+1, Abc_Clock() - clk ); diff --git a/src/proof/ssw/ssw.h b/src/proof/ssw/ssw.h index 9bd83964b..c8275b7a3 100644 --- a/src/proof/ssw/ssw.h +++ b/src/proof/ssw/ssw.h @@ -55,6 +55,7 @@ struct Ssw_Pars_t_ int nResimDelta; // the number of nodes to resimulate int nStepsMax; // (scorr only) the max number of induction steps int TimeLimit; // time out in seconds + int nLimitMax; // the limit on the number of iterations int fPolarFlip; // uses polarity adjustment int fLatchCorr; // perform register correspondence int fConstCorr; // perform constant correspondence diff --git a/src/proof/ssw/sswCore.c b/src/proof/ssw/sswCore.c index 1036d7b47..b48db9534 100644 --- a/src/proof/ssw/sswCore.c +++ b/src/proof/ssw/sswCore.c @@ -236,7 +236,7 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ) { int nSatProof, nSatCallsSat, nRecycles, nSatFailsReal, nUniques; Aig_Man_t * pAigNew; - int RetValue, nIter = -1; + int RetValue, nIter = -1, nPrev[4] = {0}; abctime clk, clkTotal = Abc_Clock(); // get the starting stats p->nLitsBeg = Ssw_ClassesLitNum( p->ppClasses ); @@ -352,7 +352,7 @@ clk = Abc_Clock(); { printf( "Iterative refinement is stopped after iteration %d\n", nIter ); printf( "because the property output is no longer a candidate constant.\n" ); - // prepare to quite + // prepare to quit p->nLitsEnd = p->nLitsBeg; p->nNodesEnd = p->nNodesBeg; p->nRegsEnd = p->nRegsBeg; @@ -381,6 +381,27 @@ clk = Abc_Clock(); break; if ( p->pPars->pFunc ) ((int (*)(void *))p->pPars->pFunc)( p->pPars->pData ); + if ( p->pPars->nLimitMax ) + { + int nCur = Ssw_ClassesCand1Num(p->ppClasses); + if ( nIter > 4 && nPrev[0] - nCur <= 4*p->pPars->nLimitMax ) + { + printf( "Iterative refinement is stopped after iteration %d\n", nIter ); + printf( "because the refinment is very slow.\n" ); + // prepare to quit + p->nLitsEnd = p->nLitsBeg; + p->nNodesEnd = p->nNodesBeg; + p->nRegsEnd = p->nRegsBeg; + // cleanup + Aig_ManSetPhase( p->pAig ); + Aig_ManCleanMarkB( p->pAig ); + return Aig_ManDupSimple( p->pAig ); + } + nPrev[0] = nPrev[1]; + nPrev[1] = nPrev[2]; + nPrev[2] = nPrev[3]; + nPrev[3] = nCur; + } } finalize: From 1f56f20e1bcd7528b526cf6d48776a606edf61fd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 09:29:52 -0700 Subject: [PATCH 45/74] Experiments with SAT sweeping. --- abclib.dsp | 12 + src/aig/gia/giaCSatP.c | 1209 ++++++++++++++++ src/aig/gia/giaCSatP.h | 117 ++ src/aig/gia/module.make | 1 + src/base/abci/abc.c | 18 +- src/proof/cec/cecSatG3.c | 2330 ++++++++++++++++++++++++++++++ src/proof/cec/module.make | 1 + src/sat/glucose2/AbcGlucose2.cpp | 6 + src/sat/glucose2/CGlucoseCore.h | 79 + src/sat/glucose2/Glucose2.cpp | 27 +- src/sat/glucose2/Solver.h | 8 + 11 files changed, 3794 insertions(+), 14 deletions(-) create mode 100644 src/aig/gia/giaCSatP.c create mode 100644 src/aig/gia/giaCSatP.h create mode 100644 src/proof/cec/cecSatG3.c diff --git a/abclib.dsp b/abclib.dsp index 23c2ce286..cf6e46e8f 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -4931,6 +4931,14 @@ SOURCE=.\src\aig\gia\giaCSatOld.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaCSatP.c +# End Source File +# Begin Source File + +SOURCE=.\src\aig\gia\giaCSatP.h +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaCTas.c # End Source File # Begin Source File @@ -5587,6 +5595,10 @@ SOURCE=.\src\proof\cec\cecSatG2.c # End Source File # Begin Source File +SOURCE=.\src\proof\cec\cecSatG3.c +# End Source File +# Begin Source File + SOURCE=.\src\proof\cec\cecSeq.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaCSatP.c b/src/aig/gia/giaCSatP.c new file mode 100644 index 000000000..00ab880b2 --- /dev/null +++ b/src/aig/gia/giaCSatP.c @@ -0,0 +1,1209 @@ +/**CFile**************************************************************** + + FileName [giaCSat.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [A simple circuit-based solver.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaCSat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "giaCSatP.h" + +ABC_NAMESPACE_IMPL_START + + +//#define gia_assert(exp) ((void)0) +//#define gia_assert(exp) (assert(exp)) + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +static inline int CbsP_VarIsAssigned( Gia_Obj_t * pVar ) { return pVar->fMark0; } +static inline void CbsP_VarAssign( Gia_Obj_t * pVar ) { assert(!pVar->fMark0); pVar->fMark0 = 1; } +static inline void CbsP_VarUnassign( CbsP_Man_t * pMan, Gia_Obj_t * pVar ) { assert(pVar->fMark0); pVar->fMark0 = 0; pVar->fMark1 = 0; pMan->vValue->pArray[Gia_ObjId(pMan->pAig,pVar)] = ~0; } +static inline int CbsP_VarValue( Gia_Obj_t * pVar ) { assert(pVar->fMark0); return pVar->fMark1; } +static inline void CbsP_VarSetValue( Gia_Obj_t * pVar, int v ) { assert(pVar->fMark0); pVar->fMark1 = v; } +static inline int CbsP_VarIsJust( Gia_Obj_t * pVar ) { return Gia_ObjIsAnd(pVar) && !CbsP_VarIsAssigned(Gia_ObjFanin0(pVar)) && !CbsP_VarIsAssigned(Gia_ObjFanin1(pVar)); } +static inline int CbsP_VarFanin0Value( Gia_Obj_t * pVar ) { return !CbsP_VarIsAssigned(Gia_ObjFanin0(pVar)) ? 2 : (CbsP_VarValue(Gia_ObjFanin0(pVar)) ^ Gia_ObjFaninC0(pVar)); } +static inline int CbsP_VarFanin1Value( Gia_Obj_t * pVar ) { return !CbsP_VarIsAssigned(Gia_ObjFanin1(pVar)) ? 2 : (CbsP_VarValue(Gia_ObjFanin1(pVar)) ^ Gia_ObjFaninC1(pVar)); } + +static inline int CbsP_VarDecLevel( CbsP_Man_t * p, Gia_Obj_t * pVar ) { int Value = p->vValue->pArray[Gia_ObjId(p->pAig,pVar)]; assert( Value != ~0 ); return Vec_IntEntry(p->vLevReas, 3*Value); } +static inline Gia_Obj_t * CbsP_VarReason0( CbsP_Man_t * p, Gia_Obj_t * pVar ) { int Value = p->vValue->pArray[Gia_ObjId(p->pAig,pVar)]; assert( Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*Value+1); } +static inline Gia_Obj_t * CbsP_VarReason1( CbsP_Man_t * p, Gia_Obj_t * pVar ) { int Value = p->vValue->pArray[Gia_ObjId(p->pAig,pVar)]; assert( Value != ~0 ); return pVar + Vec_IntEntry(p->vLevReas, 3*Value+2); } +static inline int CbsP_ClauseDecLevel( CbsP_Man_t * p, int hClause ) { return CbsP_VarDecLevel( p, p->pClauses.pData[hClause] ); } + +#define CbsP_QueForEachEntry( Que, pObj, i ) \ + for ( i = (Que).iHead; (i < (Que).iTail) && ((pObj) = (Que).pData[i]); i++ ) + +#define CbsP_ClauseForEachVar( p, hClause, pObj ) \ + for ( (p)->pIter = (p)->pClauses.pData + hClause; (pObj = *pIter); (p)->pIter++ ) +#define CbsP_ClauseForEachVar1( p, hClause, pObj ) \ + for ( (p)->pIter = (p)->pClauses.pData+hClause+1; (pObj = *pIter); (p)->pIter++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Sets default values of the parameters.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void CbsP_SetDefaultParams( CbsP_Par_t * pPars ) +{ + memset( pPars, 0, sizeof(CbsP_Par_t) ); + pPars->nBTLimit = 1000; // limit on the number of conflicts + pPars->nJustLimit = 100; // limit on the size of justification queue + pPars->fUseHighest = 1; // use node with the highest ID + pPars->fUseLowest = 0; // use node with the highest ID + pPars->fUseMaxFF = 0; // use node with the largest fanin fanout + pPars->fVerbose = 1; // print detailed statistics + + pPars->fUseProved = 1; + + + pPars->nJscanThis = 0; + pPars->nRscanThis = 0; + pPars->maxJscanUndec = 0; + pPars->maxRscanUndec = 0; + pPars->maxJscanSolved = 0; + pPars->maxRscanSolved = 0; + + + pPars->accJscanSat = 0; + pPars->accJscanUnsat = 0; + pPars->accJscanUndec = 0; + pPars->accRscanSat = 0; + pPars->accRscanUnsat = 0; + pPars->accRscanUndec = 0; + pPars->nSat = 0; + pPars->nUnsat = 0; + pPars->nUndec = 0; + + pPars->nJscanLimit = 100; + pPars->nRscanLimit = 100; + pPars->nPropLimit = 500; +} +void CbsP_ManSetConflictNum( CbsP_Man_t * p, int Num ) +{ + p->Pars.nBTLimit = Num; +} + +static inline void CbsP_UpdateRecord( CbsP_Par_t * pPars, int res ){ + if( CBS_UNDEC == res ){ + pPars->nUndec ++ ; + if( pPars-> maxJscanUndec < pPars->nJscanThis ) + pPars-> maxJscanUndec = pPars->nJscanThis; + if( pPars-> maxRscanUndec < pPars->nRscanThis ) + pPars-> maxRscanUndec = pPars->nRscanThis; + if( pPars-> maxPropUndec < pPars->nPropThis ) + pPars-> maxPropUndec = pPars->nPropThis; + + pPars->accJscanUndec += pPars->nJscanThis; + pPars->accRscanUndec += pPars->nRscanThis; + pPars-> accPropUndec += pPars->nPropThis; + } else { + if( pPars->maxJscanSolved < pPars->nJscanThis ) + pPars->maxJscanSolved = pPars->nJscanThis; + if( pPars->maxRscanSolved < pPars->nRscanThis ) + pPars->maxRscanSolved = pPars->nRscanThis; + if( pPars-> maxPropSolved < pPars->nPropThis ) + pPars-> maxPropSolved = pPars->nPropThis; + if( CBS_SAT == res ){ + pPars->nSat ++ ; + pPars->accJscanSat += pPars->nJscanThis; + pPars->accRscanSat += pPars->nRscanThis; + pPars-> accPropSat += pPars->nPropThis; + } else + if( CBS_UNSAT == res ){ + pPars->nUnsat ++ ; + pPars->accJscanUnsat += pPars->nJscanThis; + pPars->accRscanUnsat += pPars->nRscanThis; + pPars-> accPropUnsat += pPars->nPropThis; + } + } + +} + +void CbsP_PrintRecord( CbsP_Par_t * pPars ){ + printf("max of solved: jscan# %13d rscan %13d prop %13d\n" , pPars->maxJscanSolved, pPars->maxRscanSolved , pPars->maxPropSolved ); + printf("max of undec: jscan# %13d rscan %13d prop %13d\n" , pPars->maxJscanUndec , pPars->maxRscanUndec , pPars->maxPropUndec ); + printf("acc of sat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanSat , pPars->accRscanSat , pPars->accPropSat ); + printf("acc of unsat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUnsat , pPars->accRscanUnsat , pPars->accPropUnsat ); + printf("acc of undec: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUndec , pPars->accRscanUndec , pPars->accPropUndec ); + if( pPars->nSat ) + printf("avg of sat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanSat / pPars->nSat , pPars->accRscanSat / pPars->nSat , pPars->accPropSat / pPars->nSat ); + if( pPars->nUnsat ) + printf("avg of unsat: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUnsat / pPars->nUnsat , pPars->accRscanUnsat / pPars->nUnsat , pPars->accPropUnsat / pPars->nUnsat ); + if( pPars->nUndec ) + printf("avg of undec: jscan# %13ld rscan %13ld prop %13ld\n", pPars->accJscanUndec / pPars->nUndec , pPars->accRscanUndec / pPars->nUndec , pPars->accPropUndec / pPars->nUndec ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +CbsP_Man_t * CbsP_ManAlloc( Gia_Man_t * pGia ) +{ + CbsP_Man_t * p; + p = ABC_CALLOC( CbsP_Man_t, 1 ); + p->pProp.nSize = p->pJust.nSize = p->pClauses.nSize = 10000; + p->pProp.pData = ABC_ALLOC( Gia_Obj_t *, p->pProp.nSize ); + p->pJust.pData = ABC_ALLOC( Gia_Obj_t *, p->pJust.nSize ); + p->pClauses.pData = ABC_ALLOC( Gia_Obj_t *, p->pClauses.nSize ); + p->pClauses.iHead = p->pClauses.iTail = 1; + p->vModel = Vec_IntAlloc( 1000 ); + p->vLevReas = Vec_IntAlloc( 1000 ); + p->vTemp = Vec_PtrAlloc( 1000 ); + p->pAig = pGia; + p->vValue = Vec_IntAlloc( Gia_ManObjNum(pGia) ); + Vec_IntFill( p->vValue, Gia_ManObjNum(pGia), ~0 ); + //memset( p->vValue->pArray, (unsigned) ~0, sizeof(int) * Gia_ManObjNum(pGia) ); + CbsP_SetDefaultParams( &p->Pars ); + return p; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void CbsP_ManStop( CbsP_Man_t * p ) +{ + Vec_IntFree( p->vLevReas ); + Vec_IntFree( p->vModel ); + Vec_PtrFree( p->vTemp ); + Vec_IntFree( p->vValue ); + ABC_FREE( p->pClauses.pData ); + ABC_FREE( p->pProp.pData ); + ABC_FREE( p->pJust.pData ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [Returns satisfying assignment.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * CbsP_ReadModel( CbsP_Man_t * p ) +{ + return p->vModel; +} + + + + +/**Function************************************************************* + + Synopsis [Returns 1 if the solver is out of limits.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +static inline int CbsP_ManCheckPropLimits( CbsP_Man_t * p ) +{ + return p->Pars.nPropThis > p->Pars.nPropLimit; +} +static inline int CbsP_ManCheckLimits( CbsP_Man_t * p ) +{ + return CbsP_ManCheckPropLimits(p) || p->Pars.nJscanThis > p->Pars.nJscanLimit || p->Pars.nRscanThis > p->Pars.nRscanLimit || p->Pars.nJustThis > p->Pars.nJustLimit || p->Pars.nBTThis > p->Pars.nBTLimit; +} + +/**Function************************************************************* + + Synopsis [Saves the satisfying assignment as an array of literals.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_ManSaveModel( CbsP_Man_t * p, Vec_Int_t * vCex ) +{ + Gia_Obj_t * pVar; + int i; + Vec_IntClear( vCex ); + p->pProp.iHead = 0; + CbsP_QueForEachEntry( p->pProp, pVar, i ) + if ( Gia_ObjIsCi(pVar) ) + Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjId(p->pAig,pVar), !CbsP_VarValue(pVar)) ); +// Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjCioId(pVar), !CbsP_VarValue(pVar)) ); +} +static inline void CbsP_ManSaveModelAll( CbsP_Man_t * p, Vec_Int_t * vCex ) +{ + Gia_Obj_t * pVar; + int i; + Vec_IntClear( vCex ); + p->pProp.iHead = 0; + CbsP_QueForEachEntry( p->pProp, pVar, i ) + Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjId(p->pAig,pVar), !CbsP_VarValue(pVar)) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_QueIsEmpty( CbsP_Que_t * p ) +{ + return p->iHead == p->iTail; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_QuePush( CbsP_Que_t * p, Gia_Obj_t * pObj ) +{ + assert( !Gia_IsComplement(pObj) ); + if ( p->iTail == p->nSize ) + { + p->nSize *= 2; + p->pData = ABC_REALLOC( Gia_Obj_t *, p->pData, p->nSize ); + } + p->pData[p->iTail++] = pObj; +} + +/**Function************************************************************* + + Synopsis [Returns 1 if the object in the queue.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_QueHasNode( CbsP_Que_t * p, Gia_Obj_t * pObj ) +{ + Gia_Obj_t * pTemp; + int i; + CbsP_QueForEachEntry( *p, pTemp, i ) + if ( pTemp == pObj ) + return 1; + return 0; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_QueStore( CbsP_Que_t * p, int * piHeadOld, int * piTailOld ) +{ + int i; + *piHeadOld = p->iHead; + *piTailOld = p->iTail; + for ( i = *piHeadOld; i < *piTailOld; i++ ) + CbsP_QuePush( p, p->pData[i] ); + p->iHead = *piTailOld; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_QueRestore( CbsP_Que_t * p, int iHeadOld, int iTailOld ) +{ + p->iHead = iHeadOld; + p->iTail = iTailOld; +} + +/**Function************************************************************* + + Synopsis [Finalized the clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_QueFinish( CbsP_Que_t * p ) +{ + int iHeadOld = p->iHead; + assert( p->iHead < p->iTail ); + CbsP_QuePush( p, NULL ); + p->iHead = p->iTail; + return iHeadOld; +} + + +/**Function************************************************************* + + Synopsis [Max number of fanins fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_VarFaninFanoutMax( CbsP_Man_t * p, Gia_Obj_t * pObj ) +{ + int Count0, Count1; + assert( !Gia_IsComplement(pObj) ); + assert( Gia_ObjIsAnd(pObj) ); + Count0 = Gia_ObjRefNum( p->pAig, Gia_ObjFanin0(pObj) ); + Count1 = Gia_ObjRefNum( p->pAig, Gia_ObjFanin1(pObj) ); + return Abc_MaxInt( Count0, Count1 ); +} + +/**Function************************************************************* + + Synopsis [Find variable with the highest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * CbsP_ManDecideHighest( CbsP_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i; + CbsP_QueForEachEntry( p->pJust, pObj, i ) + if ( pObjMax == NULL || pObjMax < pObj ) + pObjMax = pObj; + return pObjMax; +} + +/**Function************************************************************* + + Synopsis [Find variable with the lowest ID.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * CbsP_ManDecideLowest( CbsP_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMin = NULL; + int i; + CbsP_QueForEachEntry( p->pJust, pObj, i ) + if ( pObjMin == NULL || pObjMin > pObj ) + pObjMin = pObj; + return pObjMin; +} + +/**Function************************************************************* + + Synopsis [Find variable with the maximum number of fanin fanouts.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Gia_Obj_t * CbsP_ManDecideMaxFF( CbsP_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObjMax = NULL; + int i, iMaxFF = 0, iCurFF; + assert( p->pAig->pRefs != NULL ); + CbsP_QueForEachEntry( p->pJust, pObj, i ) + { + iCurFF = CbsP_VarFaninFanoutMax( p, pObj ); + assert( iCurFF > 0 ); + if ( iMaxFF < iCurFF ) + { + iMaxFF = iCurFF; + pObjMax = pObj; + } + } + return pObjMax; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_ManCancelUntil( CbsP_Man_t * p, int iBound ) +{ + Gia_Obj_t * pVar; + int i; + assert( iBound <= p->pProp.iTail ); + p->pProp.iHead = iBound; + CbsP_QueForEachEntry( p->pProp, pVar, i ) + CbsP_VarUnassign( p, pVar ); + p->pProp.iTail = iBound; + Vec_IntShrink( p->vLevReas, 3*iBound ); +} + +//int s_Counter = 0; + +/**Function************************************************************* + + Synopsis [Assigns the variables a value.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_ManAssign( CbsP_Man_t * p, Gia_Obj_t * pObj, int Level, Gia_Obj_t * pRes0, Gia_Obj_t * pRes1 ) +{ + Gia_Obj_t * pObjR = Gia_Regular(pObj); + assert( Gia_ObjIsCand(pObjR) ); + assert( !CbsP_VarIsAssigned(pObjR) ); + CbsP_VarAssign( pObjR ); + CbsP_VarSetValue( pObjR, !Gia_IsComplement(pObj) ); + assert( p->vValue->pArray[Gia_ObjId(p->pAig,pObjR)] == ~0 ); + p->vValue->pArray[Gia_ObjId(p->pAig,pObjR)] = p->pProp.iTail; + CbsP_QuePush( &p->pProp, pObjR ); + Vec_IntPush( p->vLevReas, Level ); + Vec_IntPush( p->vLevReas, pRes0 ? pRes0-pObjR : 0 ); + Vec_IntPush( p->vLevReas, pRes1 ? pRes1-pObjR : 0 ); + assert( Vec_IntSize(p->vLevReas) == 3 * p->pProp.iTail ); + if( pRes0 ) + p->Pars.nPropThis ++ ; +// s_Counter++; +// s_Counter = Abc_MaxIntInt( s_Counter, Vec_IntSize(p->vLevReas)/3 ); +} + + +/**Function************************************************************* + + Synopsis [Returns clause size.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_ManClauseSize( CbsP_Man_t * p, int hClause ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + Gia_Obj_t ** pIter; + for ( pIter = pQue->pData + hClause; *pIter; pIter++ ); + return pIter - pQue->pData - hClause ; +} + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_ManPrintClause( CbsP_Man_t * p, int Level, int hClause ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( CbsP_QueIsEmpty( pQue ) ); + printf( "Level %2d : ", Level ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + printf( "%d=%d(%d) ", Gia_ObjId(p->pAig, pObj), CbsP_VarValue(pObj), CbsP_VarDecLevel(p, pObj) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Prints conflict clause.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_ManPrintClauseNew( CbsP_Man_t * p, int Level, int hClause ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i; + assert( CbsP_QueIsEmpty( pQue ) ); + printf( "Level %2d : ", Level ); + for ( i = hClause; (pObj = pQue->pData[i]); i++ ) + printf( "%c%d ", CbsP_VarValue(pObj)? '+':'-', Gia_ObjId(p->pAig, pObj) ); + printf( "\n" ); +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void CbsP_ManDeriveReason( CbsP_Man_t * p, int Level ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj, * pReason; + int i, k, iLitLevel; + assert( pQue->pData[pQue->iHead] == NULL ); + assert( pQue->iHead + 1 < pQue->iTail ); +/* + for ( i = pQue->iHead + 1; i < pQue->iTail; i++ ) + { + pObj = pQue->pData[i]; + assert( pObj->fMark0 == 1 ); + } +*/ + // compact literals + Vec_PtrClear( p->vTemp ); + for ( i = k = pQue->iHead + 1; i < pQue->iTail; i++ ) + { + pObj = pQue->pData[i]; + if ( !pObj->fMark0 ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fMark0 = 0; + Vec_PtrPush( p->vTemp, pObj ); + // check decision level + iLitLevel = CbsP_VarDecLevel( p, pObj ); + if ( iLitLevel < Level ) + { + pQue->pData[k++] = pObj; + continue; + } + assert( iLitLevel == Level ); + pReason = CbsP_VarReason0( p, pObj ); + if ( pReason == pObj ) // no reason + { + //assert( pQue->pData[pQue->iHead] == NULL ); + pQue->pData[pQue->iHead] = pObj; + continue; + } + CbsP_QuePush( pQue, pReason ); + pReason = CbsP_VarReason1( p, pObj ); + if ( pReason != pObj ) // second reason + CbsP_QuePush( pQue, pReason ); + } + assert( pQue->pData[pQue->iHead] != NULL ); + pQue->iTail = k; + // clear the marks + Vec_PtrForEachEntry( Gia_Obj_t *, p->vTemp, pObj, i ) + pObj->fMark0 = 1; +} + +/**Function************************************************************* + + Synopsis [Returns conflict clause.] + + Description [Performs conflict analysis.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_ManAnalyze( CbsP_Man_t * p, int Level, Gia_Obj_t * pVar, Gia_Obj_t * pFan0, Gia_Obj_t * pFan1 ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + assert( CbsP_VarIsAssigned(pVar) ); + assert( CbsP_VarIsAssigned(pFan0) ); + assert( pFan1 == NULL || CbsP_VarIsAssigned(pFan1) ); + assert( CbsP_QueIsEmpty( pQue ) ); + CbsP_QuePush( pQue, NULL ); + CbsP_QuePush( pQue, pVar ); + CbsP_QuePush( pQue, pFan0 ); + if ( pFan1 ) + CbsP_QuePush( pQue, pFan1 ); + CbsP_ManDeriveReason( p, Level ); + return CbsP_QueFinish( pQue ); +} + + +/**Function************************************************************* + + Synopsis [Performs resolution of two clauses.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_ManResolve( CbsP_Man_t * p, int Level, int hClause0, int hClause1 ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pObj; + int i, LevelMax = -1, LevelCur; + assert( pQue->pData[hClause0] != NULL ); + assert( pQue->pData[hClause0] == pQue->pData[hClause1] ); +/* + for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ ) + assert( pObj->fMark0 == 1 ); + for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ ) + assert( pObj->fMark0 == 1 ); +*/ + assert( CbsP_QueIsEmpty( pQue ) ); + CbsP_QuePush( pQue, NULL ); + for ( i = hClause0 + 1; (pObj = pQue->pData[i]); i++ ) + { + if ( !pObj->fMark0 ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fMark0 = 0; + CbsP_QuePush( pQue, pObj ); + p->Pars.nRscanThis ++ ; + LevelCur = CbsP_VarDecLevel( p, pObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = hClause1 + 1; (pObj = pQue->pData[i]); i++ ) + { + if ( !pObj->fMark0 ) // unassigned - seen again + continue; + // assigned - seen first time + pObj->fMark0 = 0; + CbsP_QuePush( pQue, pObj ); + p->Pars.nRscanThis ++ ; + LevelCur = CbsP_VarDecLevel( p, pObj ); + if ( LevelMax < LevelCur ) + LevelMax = LevelCur; + } + for ( i = pQue->iHead + 1; i < pQue->iTail; i++ ) + pQue->pData[i]->fMark0 = 1; + CbsP_ManDeriveReason( p, LevelMax ); + return CbsP_QueFinish( pQue ); +} + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns clause handle if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_ManPropagateOne( CbsP_Man_t * p, Gia_Obj_t * pVar, int Level ) +{ + int Value0, Value1; + assert( !Gia_IsComplement(pVar) ); + assert( CbsP_VarIsAssigned(pVar) ); + if ( Gia_ObjIsCi(pVar) ) + return 0; + assert( Gia_ObjIsAnd(pVar) ); + Value0 = CbsP_VarFanin0Value(pVar); + Value1 = CbsP_VarFanin1Value(pVar); + if ( CbsP_VarValue(pVar) ) + { // value is 1 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + { + if ( Value0 == 0 && Value1 != 0 ) + return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), NULL ); + if ( Value0 != 0 && Value1 == 0 ) + return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin1(pVar), NULL ); + assert( Value0 == 0 && Value1 == 0 ); + return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + } + if ( Value0 == 2 ) // first is unassigned + CbsP_ManAssign( p, Gia_ObjChild0(pVar), Level, pVar, NULL ); + if ( Value1 == 2 ) // first is unassigned + CbsP_ManAssign( p, Gia_ObjChild1(pVar), Level, pVar, NULL ); + return 0; + } + // value is 0 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + return 0; + if ( Value0 == 1 && Value1 == 1 ) // both are 1 + return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + if ( Value0 == 1 || Value1 == 1 ) // one is 1 + { + if ( Value0 == 2 ) // first is unassigned + CbsP_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) ); + if ( Value1 == 2 ) // second is unassigned + CbsP_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) ); + return 0; + } + assert( CbsP_VarIsJust(pVar) ); + assert( !CbsP_QueHasNode( &p->pJust, pVar ) ); + CbsP_QuePush( &p->pJust, pVar ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Propagates a variable.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int CbsP_ManPropagateTwo( CbsP_Man_t * p, Gia_Obj_t * pVar, int Level ) +{ + int Value0, Value1; + assert( !Gia_IsComplement(pVar) ); + assert( Gia_ObjIsAnd(pVar) ); + assert( CbsP_VarIsAssigned(pVar) ); + assert( !CbsP_VarValue(pVar) ); + Value0 = CbsP_VarFanin0Value(pVar); + Value1 = CbsP_VarFanin1Value(pVar); + // value is 0 + if ( Value0 == 0 || Value1 == 0 ) // one is 0 + return 0; + if ( Value0 == 1 && Value1 == 1 ) // both are 1 + return CbsP_ManAnalyze( p, Level, pVar, Gia_ObjFanin0(pVar), Gia_ObjFanin1(pVar) ); + assert( Value0 == 1 || Value1 == 1 ); + if ( Value0 == 2 ) // first is unassigned + CbsP_ManAssign( p, Gia_Not(Gia_ObjChild0(pVar)), Level, pVar, Gia_ObjFanin1(pVar) ); + if ( Value1 == 2 ) // first is unassigned + CbsP_ManAssign( p, Gia_Not(Gia_ObjChild1(pVar)), Level, pVar, Gia_ObjFanin0(pVar) ); + return 0; +} + +/**Function************************************************************* + + Synopsis [Propagates all variables.] + + Description [Returns 1 if conflict; 0 if no conflict.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int CbsP_ManPropagate( CbsP_Man_t * p, int Level ) +{ + int hClause; + Gia_Obj_t * pVar; + int i, k; + while ( 1 ) + { + CbsP_QueForEachEntry( p->pProp, pVar, i ) + { + if ( (hClause = CbsP_ManPropagateOne( p, pVar, Level )) ) + return hClause; + if( CbsP_ManCheckPropLimits(p) ) + return 0; + } + p->pProp.iHead = p->pProp.iTail; + k = p->pJust.iHead; + CbsP_QueForEachEntry( p->pJust, pVar, i ) + { + if ( CbsP_VarIsJust( pVar ) ) + p->pJust.pData[k++] = pVar; + else if ( (hClause = CbsP_ManPropagateTwo( p, pVar, Level )) ) + return hClause; + if( CbsP_ManCheckPropLimits(p) ) + return 0; + } + if ( k == p->pJust.iTail ) + break; + p->pJust.iTail = k; + } + return 0; +} + +/**Function************************************************************* + + Synopsis [Solve the problem recursively.] + + Description [Returns learnt clause if unsat, NULL if sat or undecided.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int CbsP_ManSolve_rec( CbsP_Man_t * p, int Level ) +{ + CbsP_Que_t * pQue = &(p->pClauses); + Gia_Obj_t * pVar = NULL, * pDecVar; + int hClause, hLearn0, hLearn1; + int iPropHead, iJustHead, iJustTail; + // propagate assignments + assert( !CbsP_QueIsEmpty(&p->pProp) ); + if ( (hClause = CbsP_ManPropagate( p, Level )) ) + return hClause; + + // quit using resource limits + if ( CbsP_ManCheckLimits( p ) ) + return 0; + // check for satisfying assignment + assert( CbsP_QueIsEmpty(&p->pProp) ); + if ( CbsP_QueIsEmpty(&p->pJust) ) + return 0; + p->Pars.nJustThis = Abc_MaxInt( p->Pars.nJustThis, p->pJust.iTail - p->pJust.iHead ); + // remember the state before branching + iPropHead = p->pProp.iHead; + CbsP_QueStore( &p->pJust, &iJustHead, &iJustTail ); + p->Pars.nJscanThis += iJustTail - iJustHead; + if ( CbsP_ManCheckLimits( p ) ) + return 0; + // find the decision variable + if ( p->Pars.fUseHighest ) + pVar = CbsP_ManDecideHighest( p ); + else if ( p->Pars.fUseLowest ) + pVar = CbsP_ManDecideLowest( p ); + else if ( p->Pars.fUseMaxFF ) + pVar = CbsP_ManDecideMaxFF( p ); + else assert( 0 ); + assert( CbsP_VarIsJust( pVar ) ); + // chose decision variable using fanout count + + if ( Gia_ObjRefNum(p->pAig, Gia_ObjFanin0(pVar)) > Gia_ObjRefNum(p->pAig, Gia_ObjFanin1(pVar)) ) + pDecVar = Gia_Not(Gia_ObjChild0(pVar)); + else + pDecVar = Gia_Not(Gia_ObjChild1(pVar)); + +// pDecVar = Gia_NotCond( Gia_Regular(pDecVar), Gia_Regular(pDecVar)->fPhase ); +// pDecVar = Gia_Not(pDecVar); + // decide on first fanin + CbsP_ManAssign( p, pDecVar, Level+1, NULL, NULL ); + if ( !(hLearn0 = CbsP_ManSolve_rec( p, Level+1 )) ) + return 0; + if ( CbsP_ManCheckLimits( p ) ) + return 0; + if ( pQue->pData[hLearn0] != Gia_Regular(pDecVar) ) + return hLearn0; + CbsP_ManCancelUntil( p, iPropHead ); + CbsP_QueRestore( &p->pJust, iJustHead, iJustTail ); + // decide on second fanin + CbsP_ManAssign( p, Gia_Not(pDecVar), Level+1, NULL, NULL ); + if ( !(hLearn1 = CbsP_ManSolve_rec( p, Level+1 )) ) + return 0; + if ( CbsP_ManCheckLimits( p ) ) + return 0; + if ( pQue->pData[hLearn1] != Gia_Regular(pDecVar) ) + return hLearn1; + hClause = CbsP_ManResolve( p, Level, hLearn0, hLearn1 ); +// CbsP_ManPrintClauseNew( p, Level, hClause ); +// if ( Level > CbsP_ClauseDecLevel(p, hClause) ) +// p->Pars.nBTThisNc++; + p->Pars.nBTThis++; + return hClause; +} + +/**Function************************************************************* + + Synopsis [Looking for a satisfying assignment of the node.] + + Description [Assumes that each node has flag pObj->fMark0 set to 0. + Returns 1 if unsatisfiable, 0 if satisfiable, and -1 if undecided. + The node may be complemented. ] + + SideEffects [The two procedures differ in the CEX format.] + + SeeAlso [] + +***********************************************************************/ +int CbsP_ManSolve( CbsP_Man_t * p, Gia_Obj_t * pObj ) +{ + int RetValue = 0; +// s_Counter = 0; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0; + CbsP_ManAssign( p, pObj, 0, NULL, NULL ); + if ( !CbsP_ManSolve_rec(p, 0) && !CbsP_ManCheckLimits(p) ) + CbsP_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + CbsP_ManCancelUntil( p, 0 ); + p->pJust.iHead = p->pJust.iTail = 0; + p->pClauses.iHead = p->pClauses.iTail = 1; + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( CbsP_ManCheckLimits( p ) ) + RetValue = -1; +// printf( "%d ", s_Counter ); + return RetValue; +} +int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ) +{ + abctime clk = Abc_Clock(); + int RetValue = 0; +// s_Counter = 0; + assert( !p->pProp.iHead && !p->pProp.iTail ); + assert( !p->pJust.iHead && !p->pJust.iTail ); + assert( p->pClauses.iHead == 1 && p->pClauses.iTail == 1 ); + p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0; + p->Pars.nJscanThis = p->Pars.nRscanThis = p->Pars.nPropThis = 0; + CbsP_ManAssign( p, pObj, 0, NULL, NULL ); + if ( pObj2 ) + CbsP_ManAssign( p, pObj2, 0, NULL, NULL ); + if ( !CbsP_ManSolve_rec(p, 0) && !CbsP_ManCheckLimits(p) ) + CbsP_ManSaveModel( p, p->vModel ); + else + RetValue = 1; + CbsP_ManCancelUntil( p, 0 ); + + p->pJust.iHead = p->pJust.iTail = 0; + p->pClauses.iHead = p->pClauses.iTail = 1; + p->Pars.nBTTotal += p->Pars.nBTThis; + p->Pars.nJustTotal = Abc_MaxInt( p->Pars.nJustTotal, p->Pars.nJustThis ); + if ( CbsP_ManCheckLimits( p ) ) + RetValue = -1; + + if( CBS_SAT == RetValue ){ + p->nSatSat ++; + p->timeSatSat += Abc_Clock() - clk; + p->nConfSat += p->Pars.nBTThis; + } else + if( CBS_UNSAT == RetValue ){ + p->nSatUnsat ++; + p->timeSatUnsat += Abc_Clock() - clk; + p->nConfUnsat += p->Pars.nBTThis; + } else { + p->nSatUndec ++; + p->timeSatUndec += Abc_Clock() - clk; + p->nConfUndec += p->Pars.nBTThis; + } +// printf( "%d ", s_Counter ); + CbsP_UpdateRecord(&p->Pars,RetValue); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [Prints statistics of the manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void CbsP_ManSatPrintStats( CbsP_Man_t * p ) +{ + printf( "CO = %8d ", Gia_ManCoNum(p->pAig) ); + printf( "AND = %8d ", Gia_ManAndNum(p->pAig) ); + printf( "Conf = %6d ", p->Pars.nBTLimit ); + printf( "JustMax = %5d ", p->Pars.nJustLimit ); + printf( "\n" ); + printf( "Unsat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUnsat, p->nSatTotal? 100.0*p->nSatUnsat/p->nSatTotal :0.0, p->nSatUnsat? 1.0*p->nConfUnsat/p->nSatUnsat :0.0 ); + ABC_PRTP( "Time", p->timeSatUnsat, p->timeTotal ); + printf( "Sat calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatSat, p->nSatTotal? 100.0*p->nSatSat/p->nSatTotal :0.0, p->nSatSat? 1.0*p->nConfSat/p->nSatSat : 0.0 ); + ABC_PRTP( "Time", p->timeSatSat, p->timeTotal ); + printf( "Undef calls %6d (%6.2f %%) Ave conf = %8.1f ", + p->nSatUndec, p->nSatTotal? 100.0*p->nSatUndec/p->nSatTotal :0.0, p->nSatUndec? 1.0*p->nConfUndec/p->nSatUndec : 0.0 ); + ABC_PRTP( "Time", p->timeSatUndec, p->timeTotal ); + ABC_PRT( "Total time", p->timeTotal ); +} + +/**Function************************************************************* + + Synopsis [Procedure to test the new SAT solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * CbsP_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose ) +{ + extern void Gia_ManCollectTest( Gia_Man_t * pAig ); + extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out ); + CbsP_Man_t * p; + Vec_Int_t * vCex, * vVisit, * vCexStore; + Vec_Str_t * vStatus; + Gia_Obj_t * pRoot; + int i, status; + abctime clk, clkTotal = Abc_Clock(); + assert( Gia_ManRegNum(pAig) == 0 ); +// Gia_ManCollectTest( pAig ); + // prepare AIG + Gia_ManCreateRefs( pAig ); + Gia_ManCleanMark0( pAig ); + Gia_ManCleanMark1( pAig ); + Gia_ManFillValue( pAig ); // maps nodes into trail ids + Gia_ManSetPhase( pAig ); // maps nodes into trail ids + // create logic network + p = CbsP_ManAlloc( pAig ); + p->Pars.nBTLimit = nConfs; + // create resulting data-structures + vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) ); + vCexStore = Vec_IntAlloc( 10000 ); + vVisit = Vec_IntAlloc( 100 ); + vCex = CbsP_ReadModel( p ); + // solve for each output + Gia_ManForEachCo( pAig, pRoot, i ) + { +// printf( "\n" ); + + Vec_IntClear( vCex ); + if ( Gia_ObjIsConst0(Gia_ObjFanin0(pRoot)) ) + { + if ( Gia_ObjFaninC0(pRoot) ) + { +// printf( "Constant 1 output of SRM!!!\n" ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); // trivial counter-example + Vec_StrPush( vStatus, 0 ); + } + else + { +// printf( "Constant 0 output of SRM!!!\n" ); + Vec_StrPush( vStatus, 1 ); + } + continue; + } + clk = Abc_Clock(); + p->Pars.fUseHighest = 1; + p->Pars.fUseLowest = 0; + status = CbsP_ManSolve( p, Gia_ObjChild0(pRoot) ); +// printf( "\n" ); +/* + if ( status == -1 ) + { + p->Pars.fUseHighest = 0; + p->Pars.fUseLowest = 1; + status = CbsP_ManSolve( p, Gia_ObjChild0(pRoot) ); + } +*/ + Vec_StrPush( vStatus, (char)status ); + if ( status == -1 ) + { + p->nSatUndec++; + p->nConfUndec += p->Pars.nBTThis; + Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout + p->timeSatUndec += Abc_Clock() - clk; + continue; + } + if ( status == 1 ) + { + if ( f0Proved ) + Gia_ManPatchCoDriver( pAig, i, 0 ); + p->nSatUnsat++; + p->nConfUnsat += p->Pars.nBTThis; + p->timeSatUnsat += Abc_Clock() - clk; + continue; + } + p->nSatSat++; + p->nConfSat += p->Pars.nBTThis; +// Gia_SatVerifyPattern( pAig, pRoot, vCex, vVisit ); + Cec_ManSatAddToStore( vCexStore, vCex, i ); + p->timeSatSat += Abc_Clock() - clk; + } + Vec_IntFree( vVisit ); + p->nSatTotal = Gia_ManPoNum(pAig); + p->timeTotal = Abc_Clock() - clkTotal; + if ( fVerbose ) + CbsP_ManSatPrintStats( p ); +// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro ); + CbsP_ManStop( p ); + *pvStatus = vStatus; + +// printf( "Total number of cex literals = %d. (Ave = %d)\n", +// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat, +// (Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat)/p->nSatSat ); + return vCexStore; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaCSatP.h b/src/aig/gia/giaCSatP.h new file mode 100644 index 000000000..4182cd144 --- /dev/null +++ b/src/aig/gia/giaCSatP.h @@ -0,0 +1,117 @@ +#ifndef ABC__aig__gia__giaCSatP_h +#define ABC__aig__gia__giaCSatP_h + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +#include "gia.h" + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_HEADER_START + + +typedef struct CbsP_Par_t_ CbsP_Par_t; +struct CbsP_Par_t_ +{ + // conflict limits + int nBTLimit; // limit on the number of conflicts + int nJustLimit; // limit on the size of justification queue + // current parameters + int nBTThis; // number of conflicts + int nBTThisNc; // number of conflicts + int nJustThis; // max size of the frontier + int nBTTotal; // total number of conflicts + int nJustTotal; // total size of the frontier + // decision heuristics + int fUseHighest; // use node with the highest ID + int fUseLowest; // use node with the highest ID + int fUseMaxFF; // use node with the largest fanin fanout + // other + int fVerbose; + int fUseProved; + + // statistics + int nJscanThis; + int nRscanThis; + int nPropThis; + int maxJscanUndec; + int maxRscanUndec; + int maxPropUndec; + int maxJscanSolved; + int maxRscanSolved; + int maxPropSolved; + int nSat, nUnsat, nUndec; + long accJscanSat; + long accJscanUnsat; + long accJscanUndec; + long accRscanSat; + long accRscanUnsat; + long accRscanUndec; + long accPropSat; + long accPropUnsat; + long accPropUndec; + + // other limits + int nJscanLimit; + int nRscanLimit; + int nPropLimit; +}; + +typedef struct CbsP_Que_t_ CbsP_Que_t; +struct CbsP_Que_t_ +{ + int iHead; // beginning of the queue + int iTail; // end of the queue + int nSize; // allocated size + Gia_Obj_t ** pData; // nodes stored in the queue +}; + +typedef struct CbsP_Man_t_ CbsP_Man_t; +struct CbsP_Man_t_ +{ + CbsP_Par_t Pars; // parameters + Gia_Man_t * pAig; // AIG manager + CbsP_Que_t pProp; // propagation queue + CbsP_Que_t pJust; // justification queue + CbsP_Que_t pClauses; // clause queue + Gia_Obj_t ** pIter; // iterator through clause vars + Vec_Int_t * vLevReas; // levels and decisions + Vec_Int_t * vValue; + Vec_Int_t * vModel; // satisfying assignment + Vec_Ptr_t * vTemp; // temporary storage + // SAT calls statistics + int nSatUnsat; // the number of proofs + int nSatSat; // the number of failure + int nSatUndec; // the number of timeouts + int nSatTotal; // the number of calls + // conflicts + int nConfUnsat; // conflicts in unsat problems + int nConfSat; // conflicts in sat problems + int nConfUndec; // conflicts in undec problems + // runtime stats + abctime timeSatUnsat; // unsat + abctime timeSatSat; // sat + abctime timeSatUndec; // undecided + abctime timeTotal; // total runtime +}; + +CbsP_Man_t * CbsP_ManAlloc( Gia_Man_t * pGia ); +void CbsP_ManStop( CbsP_Man_t * p ); +void CbsP_ManSatPrintStats( CbsP_Man_t * p ); +void CbsP_PrintRecord( CbsP_Par_t * pPars ); +int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ); + +#define CBS_UNSAT 1 +#define CBS_SAT 0 +#define CBS_UNDEC -1 + +ABC_NAMESPACE_HEADER_END + + +#endif diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index d801a2430..1cb7331c0 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -15,6 +15,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaCSat.c \ src/aig/gia/giaCSat2.c \ src/aig/gia/giaCSat3.c \ + src/aig/gia/giaCSatP.c \ src/aig/gia/giaCTas.c \ src/aig/gia/giaCut.c \ src/aig/gia/giaDecs.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 9813fc1e0..6f0f7a346 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -36996,11 +36996,12 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Gia_Man_t * Cec2_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec3_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); + extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp; - int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoG2 = 0; + int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0; Cec4_ManSetParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxwvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxywvh" ) ) != EOF ) { switch ( c ) { @@ -37125,7 +37126,10 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) fUseAlgoG ^= 1; break; case 'x': - fUseAlgoG2 ^= 1; + fUseAlgoX ^= 1; + break; + case 'y': + fUseAlgoY ^= 1; break; case 'w': pPars->fVeryVerbose ^= 1; @@ -37146,15 +37150,17 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) pTemp = Cec2_ManSimulateTest( pAbc->pGia, pPars ); else if ( fUseAlgoG ) pTemp = Cec3_ManSimulateTest( pAbc->pGia, pPars ); - else if ( fUseAlgoG2 ) + else if ( fUseAlgoX ) pTemp = Cec4_ManSimulateTest( pAbc->pGia, pPars ); + else if ( fUseAlgoY ) + pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars ); else pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 ); Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &fraig [-JWRILDCNP ] [-rmdckngwvh]\n" ); + Abc_Print( -2, "usage: &fraig [-JWRILDCNP ] [-rmdckngxywvh]\n" ); Abc_Print( -2, "\t performs combinational SAT sweeping\n" ); Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType ); Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords ); @@ -37172,6 +37178,8 @@ usage: Abc_Print( -2, "\t-k : toggle using logic cones in the SAT solver [default = %s]\n", pPars->fUseCones? "yes": "no" ); Abc_Print( -2, "\t-n : toggle using new implementation [default = %s]\n", fUseAlgo? "yes": "no" ); Abc_Print( -2, "\t-g : toggle using another new implementation [default = %s]\n", fUseAlgoG? "yes": "no" ); + Abc_Print( -2, "\t-x : toggle using another new implementation [default = %s]\n", fUseAlgoX? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle using another new implementation [default = %s]\n", fUseAlgoY? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing even more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/proof/cec/cecSatG3.c b/src/proof/cec/cecSatG3.c new file mode 100644 index 000000000..bdfa0f901 --- /dev/null +++ b/src/proof/cec/cecSatG3.c @@ -0,0 +1,2330 @@ +/**CFile**************************************************************** + + FileName [cecSatG2.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Combinational equivalence checking.] + + Synopsis [Detection of structural isomorphism.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cecSatG2.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "aig/gia/gia.h" +#include "misc/util/utilTruth.h" +#include "cec.h" +#include "aig/gia/giaCSatP.h" +#include + +#define USE_GLUCOSE2 + +#ifdef USE_GLUCOSE2 + +#include "sat/glucose2/AbcGlucose2.h" + +#define sat_solver bmcg2_sat_solver +#define sat_solver_start bmcg2_sat_solver_start +#define sat_solver_stop bmcg2_sat_solver_stop +#define sat_solver_addclause bmcg2_sat_solver_addclause +#define sat_solver_add_and bmcg2_sat_solver_add_and +#define sat_solver_add_xor bmcg2_sat_solver_add_xor +#define sat_solver_addvar bmcg2_sat_solver_addvar +#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue +#define sat_solver_reset bmcg2_sat_solver_reset +#define sat_solver_set_conflict_budget bmcg2_sat_solver_set_conflict_budget +#define sat_solver_conflictnum bmcg2_sat_solver_conflictnum +#define sat_solver_solve bmcg2_sat_solver_solve +#define sat_solver_read_cex_varvalue bmcg2_sat_solver_read_cex_varvalue +#define sat_solver_read_cex bmcg2_sat_solver_read_cex +#define sat_solver_jftr bmcg2_sat_solver_jftr +#define sat_solver_set_jftr bmcg2_sat_solver_set_jftr +#define sat_solver_set_var_fanin_lit bmcg2_sat_solver_set_var_fanin_lit +#define sat_solver_start_new_round bmcg2_sat_solver_start_new_round +#define sat_solver_mark_cone bmcg2_sat_solver_mark_cone + +#else + +#include "sat/glucose/AbcGlucose.h" + +#define sat_solver bmcg_sat_solver +#define sat_solver_start bmcg_sat_solver_start +#define sat_solver_stop bmcg_sat_solver_stop +#define sat_solver_addclause bmcg_sat_solver_addclause +#define sat_solver_add_and bmcg_sat_solver_add_and +#define sat_solver_add_xor bmcg_sat_solver_add_xor +#define sat_solver_addvar bmcg_sat_solver_addvar +#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue +#define sat_solver_reset bmcg_sat_solver_reset +#define sat_solver_set_conflict_budget bmcg_sat_solver_set_conflict_budget +#define sat_solver_conflictnum bmcg_sat_solver_conflictnum +#define sat_solver_solve bmcg_sat_solver_solve +#define sat_solver_read_cex_varvalue bmcg_sat_solver_read_cex_varvalue +#define sat_solver_read_cex bmcg_sat_solver_read_cex +#define sat_solver_jftr bmcg_sat_solver_jftr +#define sat_solver_set_jftr bmcg_sat_solver_set_jftr +#define sat_solver_set_var_fanin_lit bmcg_sat_solver_set_var_fanin_lit +#define sat_solver_start_new_round bmcg_sat_solver_start_new_round +#define sat_solver_mark_cone bmcg_sat_solver_mark_cone + +#endif + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +// SAT solving manager +typedef struct Cec5_Man_t_ Cec5_Man_t; +struct Cec5_Man_t_ +{ + Cec_ParFra_t * pPars; // parameters + Gia_Man_t * pAig; // user's AIG + Gia_Man_t * pNew; // internal AIG + // SAT solving + sat_solver * pSat; // SAT solver + Vec_Ptr_t * vFrontier; // CNF construction + Vec_Ptr_t * vFanins; // CNF construction + Vec_Int_t * vCexMin; // minimized CEX + Vec_Int_t * vClassUpdates; // updated equiv classes + Vec_Int_t * vCexStamps; // time stamps + Vec_Int_t * vCands; + Vec_Int_t * vVisit; + Vec_Int_t * vPat; + Vec_Int_t * vDisprPairs; + Vec_Bit_t * vFails; + Vec_Bit_t * vCoDrivers; + int iPosRead; // candidate reading position + int iPosWrite; // candidate writing position + int iLastConst; // last const node proved + // refinement + Vec_Int_t * vRefClasses; + Vec_Int_t * vRefNodes; + Vec_Int_t * vRefBins; + int * pTable; + int nTableSize; + // statistics + int nItersSim; + int nItersSat; + int nAndNodes; + int nPatterns; + int nSatSat; + int nSatUnsat; + int nSatUndec; + int nCallsSince; + int nSimulates; + int nRecycles; + int nConflicts[3][3]; + int nGates[2]; + int nFaster[2]; + abctime timeCnf; + abctime timeGenPats; + abctime timeSatSat0; + abctime timeSatUnsat0; + abctime timeSatSat; + abctime timeSatUnsat; + abctime timeSatUndec; + abctime timeSim; + abctime timeRefine; + abctime timeResimGlo; + abctime timeResimLoc; + abctime timeStart; + + int simTravId; + Vec_Int_t * vPiPatsCache; + int fEec; + int LocalBatchSize; + Vec_Bit_t * vCexSite; + int simBound; + int simStart; + int approxLim; + int simGlobalTop; + int simBatchFactor; + int adaRecycle; +}; + +static inline int Cec5_ObjSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Gia_ObjCopy2Array(p, Gia_ObjId(p, pObj)); } +static inline int Cec5_ObjSetSatId( Gia_Man_t * p, Gia_Obj_t * pObj, int Num ) { assert(Cec5_ObjSatId(p, pObj) == -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), Num); Vec_IntPush(&p->vSuppVars, Gia_ObjId(p, pObj)); if ( Gia_ObjIsCi(pObj) ) Vec_IntPushTwo(&p->vCopiesTwo, Gia_ObjId(p, pObj), Num); assert(Vec_IntSize(&p->vVarMap) == Num); Vec_IntPush(&p->vVarMap, Gia_ObjId(p, pObj)); return Num; } +static inline void Cec5_ObjCleanSatId( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert(Cec5_ObjSatId(p, pObj) != -1); Gia_ObjSetCopy2Array(p, Gia_ObjId(p, pObj), -1); } + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Cec5_EvalCombine( Vec_Int_t * vPats, int nPats, int nInputs, int nWords ) +{ + //Vec_Wrd_t * vSimsPi = Vec_WrdStart( nInputs * nWords ); + Vec_Wrd_t * vSimsPi = Vec_WrdStartRandom( nInputs * nWords ); + int i, k, iLit, iPat = 0; word * pSim; + for ( i = 0; i < Vec_IntSize(vPats); i += Vec_IntEntry(vPats, i), iPat++ ) + for ( k = 1; k < Vec_IntEntry(vPats, i)-1; k++ ) + if ( (iLit = Vec_IntEntry(vPats, i+k)) ) + { + assert( Abc_Lit2Var(iLit) > 0 && Abc_Lit2Var(iLit) <= nInputs ); + pSim = Vec_WrdEntryP( vSimsPi, (Abc_Lit2Var(iLit)-1)*nWords ); + if ( Abc_InfoHasBit( (unsigned*)pSim, iPat ) != Abc_LitIsCompl(iLit) ) + Abc_InfoXorBit( (unsigned*)pSim, iPat ); + } + assert( iPat == nPats ); + return vSimsPi; +} +void Cec5_EvalPatterns( Gia_Man_t * p, Vec_Int_t * vPats, int nPats ) +{ + int nWords = Abc_Bit6WordNum(nPats); + Vec_Wrd_t * vSimsPi = Cec5_EvalCombine( vPats, nPats, Gia_ManCiNum(p), nWords ); + Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( p, vSimsPi, 1 ); + int i, Count = 0, nErrors = 0; + for ( i = 0; i < Gia_ManCoNum(p); i++ ) + { + int CountThis = Abc_TtCountOnesVec( Vec_WrdEntryP(vSimsPo, i*nWords), nWords ); + if ( CountThis == 0 ) + continue; + printf( "%d ", CountThis ); + nErrors += CountThis; + Count++; + } + printf( "\nDetected %d error POs with %d errors (average %.2f).\n", Count, nErrors, 1.0*nErrors/Abc_MaxInt(1, Count) ); + Vec_WrdFree( vSimsPi ); + Vec_WrdFree( vSimsPo ); +} + +/**Function************************************************************* + + Synopsis [Default parameter settings.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec5_ManSetParams( Cec_ParFra_t * pPars ) +{ + memset( pPars, 0, sizeof(Cec_ParFra_t) ); + pPars->jType = 2; // solver type + pPars->fSatSweeping = 1; // conflict limit at a node + pPars->nWords = 4; // simulation words + pPars->nRounds = 10; // simulation rounds + pPars->nItersMax = 2000; // this is a miter + pPars->nBTLimit = 1000000; // use logic cones + pPars->nBTLimitPo = 0; // use logic outputs + pPars->nSatVarMax = 1000; // the max number of SAT variables before recycling SAT solver + pPars->nCallsRecycle = 500; // calls to perform before recycling SAT solver + pPars->nGenIters = 100; // pattern generation iterations +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Cec5_Man_t * Cec5_ManCreate( Gia_Man_t * pAig, Cec_ParFra_t * pPars ) +{ + Cec5_Man_t * p = ABC_CALLOC( Cec5_Man_t, 1 ); + memset( p, 0, sizeof(Cec5_Man_t) ); + p->timeStart = Abc_Clock(); + p->pPars = pPars; + p->pAig = pAig; + p->pSat = sat_solver_start(); + sat_solver_set_jftr( p->pSat, pPars->jType ); + p->vFrontier = Vec_PtrAlloc( 1000 ); + p->vFanins = Vec_PtrAlloc( 100 ); + p->vCexMin = Vec_IntAlloc( 100 ); + p->vClassUpdates = Vec_IntAlloc( 100 ); + p->vCexStamps = Vec_IntStart( Gia_ManObjNum(pAig) ); + p->vCands = Vec_IntAlloc( 100 ); + p->vVisit = Vec_IntAlloc( 100 ); + p->vPat = Vec_IntAlloc( 100 ); + p->vDisprPairs = Vec_IntAlloc( 100 ); + p->vFails = Vec_BitStart( Gia_ManObjNum(pAig) ); + //pAig->pData = p->pSat; // point AIG manager to the solver + //Vec_IntFreeP( &p->pAig->vPats ); + //p->pAig->vPats = Vec_IntAlloc( 1000 ); + p->simTravId = 0; + p->vPiPatsCache = Vec_IntAlloc( 100 ); + p->fEec = 0; + p->LocalBatchSize= 8; + p->vCexSite = Vec_BitStart( Gia_ManObjNum(pAig) ); + Vec_BitFill( p->vCexSite, Gia_ManObjNum(pAig), 0 ); + p->simBound = pPars->nWords; + p->simStart = 0; + p->approxLim = 600; + p->simBatchFactor= 1; + p->simGlobalTop = 0; + p->adaRecycle = 500; + if ( pPars->nBTLimitPo ) + { + int i, Driver; + p->vCoDrivers = Vec_BitStart( Gia_ManObjNum(pAig) ); + Gia_ManForEachCoDriverId( pAig, Driver, i ) + Vec_BitWriteEntry( p->vCoDrivers, Driver, 1 ); + } + return p; +} +void Cec5_ManDestroy( Cec5_Man_t * p ) +{ + if ( p->pPars->fVerbose ) + { + abctime timeTotal = Abc_Clock() - p->timeStart; + abctime timeSat = p->timeSatSat0 + p->timeSatSat + p->timeSatUnsat0 + p->timeSatUnsat + p->timeSatUndec; + abctime timeOther = timeTotal - timeSat - p->timeSim - p->timeRefine - p->timeResimLoc - p->timeGenPats;// - p->timeResimGlo; + ABC_PRTP( "SAT solving ", timeSat, timeTotal ); + ABC_PRTP( " sat(easy) ", p->timeSatSat0, timeTotal ); + ABC_PRTP( " sat ", p->timeSatSat, timeTotal ); + ABC_PRTP( " unsat(easy)", p->timeSatUnsat0, timeTotal ); + ABC_PRTP( " unsat ", p->timeSatUnsat, timeTotal ); + ABC_PRTP( " fail ", p->timeSatUndec, timeTotal ); + ABC_PRTP( "Generate CNF ", p->timeCnf, timeTotal ); + ABC_PRTP( "Generate pats", p->timeGenPats, timeTotal ); + ABC_PRTP( "Simulation ", p->timeSim, timeTotal ); + ABC_PRTP( "Refinement ", p->timeRefine, timeTotal ); + ABC_PRTP( "Resim global ", p->timeResimGlo, timeTotal ); + ABC_PRTP( "Resim local ", p->timeResimLoc, timeTotal ); + ABC_PRTP( "Other ", timeOther, timeTotal ); + ABC_PRTP( "TOTAL ", timeTotal, timeTotal ); + fflush( stdout ); + } + //printf( "Recorded %d patterns with %d literals (average %.2f).\n", + // p->pAig->nBitPats, Vec_IntSize(p->pAig->vPats) - 2*p->pAig->nBitPats, 1.0*Vec_IntSize(p->pAig->vPats)/Abc_MaxInt(1, p->pAig->nBitPats)-2 ); + //Cec5_EvalPatterns( p->pAig, p->pAig->vPats, p->pAig->nBitPats ); + //Vec_IntFreeP( &p->pAig->vPats ); + Vec_WrdFreeP( &p->pAig->vSims ); + Vec_WrdFreeP( &p->pAig->vSimsPi ); + Gia_ManCleanMark01( p->pAig ); + sat_solver_stop( p->pSat ); + Gia_ManStopP( &p->pNew ); + Vec_PtrFreeP( &p->vFrontier ); + Vec_PtrFreeP( &p->vFanins ); + Vec_IntFreeP( &p->vCexMin ); + Vec_IntFreeP( &p->vClassUpdates ); + Vec_IntFreeP( &p->vCexStamps ); + Vec_IntFreeP( &p->vCands ); + Vec_IntFreeP( &p->vVisit ); + Vec_IntFreeP( &p->vPat ); + Vec_IntFreeP( &p->vDisprPairs ); + Vec_BitFreeP( &p->vFails ); + Vec_BitFreeP( &p->vCoDrivers ); + Vec_IntFreeP( &p->vRefClasses ); + Vec_IntFreeP( &p->vRefNodes ); + Vec_IntFreeP( &p->vRefBins ); + Vec_IntFreeP( &p->vPiPatsCache ); + Vec_BitFreeP( &p->vCexSite ); + ABC_FREE( p->pTable ); + ABC_FREE( p ); +} +Gia_Man_t * Cec5_ManStartNew( Gia_Man_t * pAig ) +{ + Gia_Obj_t * pObj; int i; + Gia_Man_t * pNew = Gia_ManStart( Gia_ManObjNum(pAig) ); + pNew->pName = Abc_UtilStrsav( pAig->pName ); + pNew->pSpec = Abc_UtilStrsav( pAig->pSpec ); + if ( pAig->pMuxes ) + pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc ); + Gia_ManFillValue( pAig ); + Gia_ManConst0(pAig)->Value = 0; + Gia_ManForEachCi( pAig, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManHashAlloc( pNew ); + Vec_IntFill( &pNew->vCopies2, Gia_ManObjNum(pAig), -1 ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(pAig) ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Adds clauses to the solver.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec5_AddClausesMux( Gia_Man_t * p, Gia_Obj_t * pNode, sat_solver * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pNodeI, * pNodeT, * pNodeE; + int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; + + assert( !Gia_IsComplement( pNode ) ); + assert( pNode->fMark0 ); + // get nodes (I = if, T = then, E = else) + pNodeI = Gia_ObjRecognizeMux( pNode, &pNodeT, &pNodeE ); + // get the variable numbers + VarF = Cec5_ObjSatId(p, pNode); + VarI = Cec5_ObjSatId(p, pNodeI); + VarT = Cec5_ObjSatId(p, Gia_Regular(pNodeT)); + VarE = Cec5_ObjSatId(p, Gia_Regular(pNodeE)); + // get the complementation flags + fCompT = Gia_IsComplement(pNodeT); + fCompE = Gia_IsComplement(pNodeE); + + // f = ITE(i, t, e) + + // i' + t' + f + // i' + t + f' + // i + e' + f + // i + e + f' + + // create four clauses + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 1); + pLits[1] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeT)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarI, 0); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( pNodeI->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + + // two additional clauses + // t' & e' -> f' + // t & e -> f + + // t + e + f' + // t' + e' + f + + if ( VarT == VarE ) + { +// assert( fCompT == !fCompE ); + return; + } + + pLits[0] = Abc_Var2Lit(VarT, 0^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 0^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); + pLits[0] = Abc_Var2Lit(VarT, 1^fCompT); + pLits[1] = Abc_Var2Lit(VarE, 1^fCompE); + pLits[2] = Abc_Var2Lit(VarF, 0); + if ( fPolarFlip ) + { + if ( Gia_Regular(pNodeT)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( Gia_Regular(pNodeE)->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + if ( pNode->fPhase ) pLits[2] = Abc_LitNot( pLits[2] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 3 ); + assert( RetValue ); +} +void Cec5_AddClausesSuper( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Ptr_t * vSuper, sat_solver * pSat ) +{ + int fPolarFlip = 0; + Gia_Obj_t * pFanin; + int * pLits, nLits, RetValue, i; + assert( !Gia_IsComplement(pNode) ); + assert( Gia_ObjIsAnd( pNode ) ); + // create storage for literals + nLits = Vec_PtrSize(vSuper) + 1; + pLits = ABC_ALLOC( int, nLits ); + // suppose AND-gate is A & B = C + // add !A => !C or A + !C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[0] = Abc_Var2Lit(Cec5_ObjSatId(p, Gia_Regular(pFanin)), Gia_IsComplement(pFanin)); + pLits[1] = Abc_Var2Lit(Cec5_ObjSatId(p, pNode), 1); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[0] = Abc_LitNot( pLits[0] ); + if ( pNode->fPhase ) pLits[1] = Abc_LitNot( pLits[1] ); + } + RetValue = sat_solver_addclause( pSat, pLits, 2 ); + assert( RetValue ); + } + // add A & B => C or !A + !B + C + Vec_PtrForEachEntry( Gia_Obj_t *, vSuper, pFanin, i ) + { + pLits[i] = Abc_Var2Lit(Cec5_ObjSatId(p, Gia_Regular(pFanin)), !Gia_IsComplement(pFanin)); + if ( fPolarFlip ) + { + if ( Gia_Regular(pFanin)->fPhase ) pLits[i] = Abc_LitNot( pLits[i] ); + } + } + pLits[nLits-1] = Abc_Var2Lit(Cec5_ObjSatId(p, pNode), 0); + if ( fPolarFlip ) + { + if ( pNode->fPhase ) pLits[nLits-1] = Abc_LitNot( pLits[nLits-1] ); + } + RetValue = sat_solver_addclause( pSat, pLits, nLits ); + assert( RetValue ); + ABC_FREE( pLits ); +} + +/**Function************************************************************* + + Synopsis [Adds clauses and returns CNF variable of the node.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec5_CollectSuper_rec( Gia_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes ) +{ + // if the new node is complemented or a PI, another gate begins + if ( Gia_IsComplement(pObj) || Gia_ObjIsCi(pObj) || + (!fFirst && Gia_ObjValue(pObj) > 1) || + (fUseMuxes && pObj->fMark0) ) + { + Vec_PtrPushUnique( vSuper, pObj ); + return; + } + // go through the branches + Cec5_CollectSuper_rec( Gia_ObjChild0(pObj), vSuper, 0, fUseMuxes ); + Cec5_CollectSuper_rec( Gia_ObjChild1(pObj), vSuper, 0, fUseMuxes ); +} +void Cec5_CollectSuper( Gia_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsCi(pObj) ); + Vec_PtrClear( vSuper ); + Cec5_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes ); +} +void Cec5_ObjAddToFrontier( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Ptr_t * vFrontier, sat_solver * pSat ) +{ + assert( !Gia_IsComplement(pObj) ); + assert( !Gia_ObjIsConst0(pObj) ); + if ( Cec5_ObjSatId(p, pObj) >= 0 ) + return; + assert( Cec5_ObjSatId(p, pObj) == -1 ); + Cec5_ObjSetSatId( p, pObj, sat_solver_addvar(pSat) ); + if ( Gia_ObjIsAnd(pObj) ) + Vec_PtrPush( vFrontier, pObj ); +} +int Cec5_ObjGetCnfVar( Cec5_Man_t * p, int iObj ) +{ + int fUseSimple = 1; // enable simple CNF + int fUseMuxes = 1; // enable MUXes when using complex CNF + Gia_Obj_t * pNode, * pFanin; + Gia_Obj_t * pObj = Gia_ManObj(p->pNew, iObj); + int i, k; + // quit if CNF is ready + if ( Cec5_ObjSatId(p->pNew,pObj) >= 0 ) + return Cec5_ObjSatId(p->pNew,pObj); + + assert( iObj > 0 ); + if ( Gia_ObjIsCi(pObj) ) + return Cec5_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) ); + assert( Gia_ObjIsAnd(pObj) ); + if ( fUseSimple ) + { + Gia_Obj_t * pFan0, * pFan1; + //if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + // printf( "%d", (Gia_IsComplement(pFan1) << 1) + Gia_IsComplement(pFan0) ); + if ( p->pNew->pMuxes == NULL && Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) && Gia_IsComplement(pFan0) == Gia_IsComplement(pFan1) ) + { + int iVar0 = Cec5_ObjGetCnfVar( p, Gia_ObjId(p->pNew, Gia_Regular(pFan0)) ); + int iVar1 = Cec5_ObjGetCnfVar( p, Gia_ObjId(p->pNew, Gia_Regular(pFan1)) ); + int iVar = Cec5_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) ); + if ( p->pPars->jType < 2 ) + sat_solver_add_xor( p->pSat, iVar, iVar0, iVar1, 0 ); + if ( p->pPars->jType > 0 ) + { + int Lit0 = Abc_Var2Lit( iVar0, 0 ); + int Lit1 = Abc_Var2Lit( iVar1, 0 ); + if ( Lit0 < Lit1 ) + Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0; + assert( Lit0 > Lit1 ); + sat_solver_set_var_fanin_lit( p->pSat, iVar, Lit0, Lit1 ); + p->nGates[1]++; + } + } + else + { + int iVar0 = Cec5_ObjGetCnfVar( p, Gia_ObjFaninId0(pObj, iObj) ); + int iVar1 = Cec5_ObjGetCnfVar( p, Gia_ObjFaninId1(pObj, iObj) ); + int iVar = Cec5_ObjSetSatId( p->pNew, pObj, sat_solver_addvar(p->pSat) ); + if ( p->pPars->jType < 2 ) + { + if ( Gia_ObjIsXor(pObj) ) + sat_solver_add_xor( p->pSat, iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) ); + else + sat_solver_add_and( p->pSat, iVar, iVar0, iVar1, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 ); + } + if ( p->pPars->jType > 0 ) + { + int Lit0 = Abc_Var2Lit( iVar0, Gia_ObjFaninC0(pObj) ); + int Lit1 = Abc_Var2Lit( iVar1, Gia_ObjFaninC1(pObj) ); + if ( (Lit0 > Lit1) ^ Gia_ObjIsXor(pObj) ) + Lit1 ^= Lit0, Lit0 ^= Lit1, Lit1 ^= Lit0; + sat_solver_set_var_fanin_lit( p->pSat, iVar, Lit0, Lit1 ); + p->nGates[Gia_ObjIsXor(pObj)]++; + } + } + return Cec5_ObjSatId( p->pNew, pObj ); + } + assert( !Gia_ObjIsXor(pObj) ); + // start the frontier + Vec_PtrClear( p->vFrontier ); + Cec5_ObjAddToFrontier( p->pNew, pObj, p->vFrontier, p->pSat ); + // explore nodes in the frontier + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFrontier, pNode, i ) + { + // create the supergate + assert( Cec5_ObjSatId(p->pNew,pNode) >= 0 ); + if ( fUseMuxes && pNode->fMark0 ) + { + Vec_PtrClear( p->vFanins ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin0( Gia_ObjFanin1(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin0(pNode) ) ); + Vec_PtrPushUnique( p->vFanins, Gia_ObjFanin1( Gia_ObjFanin1(pNode) ) ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec5_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec5_AddClausesMux( p->pNew, pNode, p->pSat ); + } + else + { + Cec5_CollectSuper( pNode, fUseMuxes, p->vFanins ); + Vec_PtrForEachEntry( Gia_Obj_t *, p->vFanins, pFanin, k ) + Cec5_ObjAddToFrontier( p->pNew, Gia_Regular(pFanin), p->vFrontier, p->pSat ); + Cec5_AddClausesSuper( p->pNew, pNode, p->vFanins, p->pSat ); + } + assert( Vec_PtrSize(p->vFanins) > 1 ); + } + return Cec5_ObjSatId(p->pNew,pObj); +} + + +/**Function************************************************************* + + Synopsis [Refinement of equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word * Cec5_ObjSim( Gia_Man_t * p, int iObj ) +{ + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); +} +static inline int Cec5_ObjSimEqual( Gia_Man_t * p, int iObj0, int iObj1 ) +{ + int w; + word * pSim0 = Cec5_ObjSim( p, iObj0 ); + word * pSim1 = Cec5_ObjSim( p, iObj1 ); + if ( (pSim0[0] & 1) == (pSim1[0] & 1) ) + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != pSim1[w] ) + return 0; + return 1; + } + else + { + for ( w = 0; w < p->nSimWords; w++ ) + if ( pSim0[w] != ~pSim1[w] ) + return 0; + return 1; + } +} +int Cec5_ManSimHashKey( word * pSim, int nSims, int nTableSize ) +{ + static int s_Primes[16] = { + 1291, 1699, 1999, 2357, 2953, 3313, 3907, 4177, + 4831, 5147, 5647, 6343, 6899, 7103, 7873, 8147 }; + unsigned uHash = 0, * pSimU = (unsigned *)pSim; + int i, nSimsU = 2 * nSims; + if ( pSimU[0] & 1 ) + for ( i = 0; i < nSimsU; i++ ) + uHash ^= ~pSimU[i] * s_Primes[i & 0xf]; + else + for ( i = 0; i < nSimsU; i++ ) + uHash ^= pSimU[i] * s_Primes[i & 0xf]; + return (int)(uHash % nTableSize); + +} +void Cec5_RefineOneClassIter( Gia_Man_t * p, int iRepr ) +{ + int iObj, iPrev = iRepr, iPrev2, iRepr2; + assert( Gia_ObjRepr(p, iRepr) == GIA_VOID ); + assert( Gia_ObjNext(p, iRepr) > 0 ); + Gia_ClassForEachObj1( p, iRepr, iRepr2 ) + if ( Cec5_ObjSimEqual(p, iRepr, iRepr2) ) + iPrev = iRepr2; + else + break; + if ( iRepr2 <= 0 ) // no refinement + return; + // relink remaining nodes of the class + // nodes that are equal to iRepr, remain in the class of iRepr + // nodes that are not equal to iRepr, move to the class of iRepr2 + Gia_ObjSetRepr( p, iRepr2, GIA_VOID ); + assert( !Gia_ObjProved(p,iRepr2) ); + iPrev2 = iRepr2; + for ( iObj = Gia_ObjNext(p, iRepr2); iObj > 0; iObj = Gia_ObjNext(p, iObj) ) + { + if ( Cec5_ObjSimEqual(p, iRepr, iObj) ) // remains with iRepr + { + Gia_ObjSetNext( p, iPrev, iObj ); + iPrev = iObj; + } + else // moves to iRepr2 + { + Gia_ObjSetRepr( p, iObj, iRepr2 ); + Gia_ObjSetNext( p, iPrev2, iObj ); + iPrev2 = iObj; + } + } + Gia_ObjSetNext( p, iPrev, -1 ); + Gia_ObjSetNext( p, iPrev2, -1 ); + // refine incrementally + if ( Gia_ObjNext(p, iRepr2) > 0 ) + Cec5_RefineOneClassIter( p, iRepr2 ); +} +void Cec5_RefineOneClass( Gia_Man_t * p, Cec5_Man_t * pMan, Vec_Int_t * vNodes ) +{ + int k, iObj, Bin; + Vec_IntClear( pMan->vRefBins ); + Vec_IntForEachEntryReverse( vNodes, iObj, k ) + { + int Key = Cec5_ManSimHashKey( Cec5_ObjSim(p, iObj), p->nSimWords, pMan->nTableSize ); + assert( Key >= 0 && Key < pMan->nTableSize ); + if ( pMan->pTable[Key] == -1 ) + Vec_IntPush( pMan->vRefBins, Key ); + p->pNexts[iObj] = pMan->pTable[Key]; + pMan->pTable[Key] = iObj; + } + Vec_IntForEachEntry( pMan->vRefBins, Bin, k ) + { + int iRepr = pMan->pTable[Bin]; + pMan->pTable[Bin] = -1; + assert( p->pReprs[iRepr].iRepr == GIA_VOID ); + assert( p->pNexts[iRepr] != 0 ); + assert( !Gia_ObjProved(p,iRepr) ); + if ( p->pNexts[iRepr] == -1 ) + continue; + for ( iObj = p->pNexts[iRepr]; iObj > 0; iObj = p->pNexts[iObj] ) + p->pReprs[iObj].iRepr = iRepr; + Cec5_RefineOneClassIter( p, iRepr ); + } + Vec_IntClear( pMan->vRefBins ); +} +void Cec5_RefineClasses( Gia_Man_t * p, Cec5_Man_t * pMan, Vec_Int_t * vClasses ) +{ + if ( Vec_IntSize(pMan->vRefClasses) == 0 ) + return; + if ( Vec_IntSize(pMan->vRefNodes) > 0 ) + Cec5_RefineOneClass( p, pMan, pMan->vRefNodes ); + else + { + int i, k, iObj, iRepr; + Vec_IntForEachEntry( pMan->vRefClasses, iRepr, i ) + { + assert( p->pReprs[iRepr].fColorA ); + p->pReprs[iRepr].fColorA = 0; + Vec_IntClear( pMan->vRefNodes ); + Vec_IntPush( pMan->vRefNodes, iRepr ); + Gia_ClassForEachObj1( p, iRepr, k ) + Vec_IntPush( pMan->vRefNodes, k ); + Vec_IntForEachEntry( pMan->vRefNodes, iObj, k ) + { + p->pReprs[iObj].iRepr = GIA_VOID; + p->pNexts[iObj] = -1; + } + Cec5_RefineOneClass( p, pMan, pMan->vRefNodes ); + } + } + Vec_IntClear( pMan->vRefClasses ); + Vec_IntClear( pMan->vRefNodes ); +} +void Cec5_RefineInit( Gia_Man_t * p, Cec5_Man_t * pMan ) +{ + Gia_Obj_t * pObj; int i; + if( pMan->fEec ){ + assert( p->pReprs ); + assert( p->pNexts ); + } else { + ABC_FREE( p->pReprs ); + ABC_FREE( p->pNexts ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + p->pNexts = ABC_FALLOC( int, Gia_ManObjNum(p) ); + } + + pMan->nTableSize = Abc_PrimeCudd( Gia_ManObjNum(p) ); + pMan->pTable = ABC_FALLOC( int, pMan->nTableSize ); + pMan->vRefNodes = Vec_IntAlloc( Gia_ManObjNum(p) ); + + pMan->vRefBins = Vec_IntAlloc( Gia_ManObjNum(p)/2 ); + pMan->vRefClasses = Vec_IntAlloc( Gia_ManObjNum(p)/2 ); + + if( pMan->fEec ) return; + + Gia_ManForEachObj( p, pObj, i ) + { + p->pReprs[i].iRepr = GIA_VOID; + if ( !Gia_ObjIsCo(pObj) && (!pMan->pPars->nLevelMax || Gia_ObjLevel(p, pObj) <= pMan->pPars->nLevelMax) ) + Vec_IntPush( pMan->vRefNodes, i ); + } + + Vec_IntPush( pMan->vRefClasses, 0 ); +} + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Cec5_ObjSimSetInputBit( Gia_Man_t * p, int iObj, int Bit ) +{ + word * pSim = Cec5_ObjSim( p, iObj ); + if ( Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ) != Bit ) + Abc_InfoXorBit( (unsigned*)pSim, p->iPatsPi ); +} +static inline int Cec5_ObjSimGetInputBit( Gia_Man_t * p, int iObj ) +{ + word * pSim = Cec5_ObjSim( p, iObj ); + return Abc_InfoHasBit( (unsigned*)pSim, p->iPatsPi ); +} +static inline void Cec5_ObjSimRo( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSimRo = Cec5_ObjSim( p, iObj ); + word * pSimRi = Cec5_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); + for ( w = 0; w < p->nSimWords; w++ ) + pSimRo[w] = pSimRi[w]; +} +static inline void Cec5_ObjSimCo( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSimCo = Cec5_ObjSim( p, iObj ); + word * pSimDri = Cec5_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = ~pSimDri[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = pSimDri[w]; +} +static inline void Cec5_ObjSimAnd( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSim = Cec5_ObjSim( p, iObj ); + word * pSim0 = Cec5_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + word * pSim1 = Cec5_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = pMan->simStart; w < pMan->simBound; w++ ) + pSim[w] = ~pSim0[w] & ~pSim1[w]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( w = pMan->simStart; w < pMan->simBound; w++ ) + pSim[w] = ~pSim0[w] & pSim1[w]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = pMan->simStart; w < pMan->simBound; w++ ) + pSim[w] = pSim0[w] & ~pSim1[w]; + else + for ( w = pMan->simStart; w < pMan->simBound; w++ ) + pSim[w] = pSim0[w] & pSim1[w]; +} +static inline void Cec5_ObjSimXor( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSim = Cec5_ObjSim( p, iObj ); + word * pSim0 = Cec5_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + word * pSim1 = Cec5_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) ) + for ( w = pMan->simStart; w < pMan->simBound; w++ ) + pSim[w] = ~pSim0[w] ^ pSim1[w]; + else + for ( w = pMan->simStart; w < pMan->simBound; w++ ) + pSim[w] = pSim0[w] ^ pSim1[w]; +} +static inline void Cec5_ObjSimCi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Cec5_ObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = Gia_ManRandomW( 0 ); + pSim[0] <<= 1; +} +static inline void Cec5_ObjClearSimCi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Cec5_ObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = 0; +} +void Cec5_ManSimulateCis( Gia_Man_t * p ) +{ + int i, Id; + Gia_ManForEachCiId( p, Id, i ) + Cec5_ObjSimCi( p, Id ); + p->iPatsPi = 0; +} +void Cec5_ManClearCis( Gia_Man_t * p ) +{ + int i, Id; + Gia_ManForEachCiId( p, Id, i ) + Cec5_ObjClearSimCi( p, Id ); + p->iPatsPi = 0; +} +Abc_Cex_t * Cec5_ManDeriveCex( Gia_Man_t * p, int iOut, int iPat ) +{ + Abc_Cex_t * pCex; + int i, Id; + pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p), 1 ); + pCex->iPo = iOut; + if ( iPat == -1 ) + return pCex; + Gia_ManForEachCiId( p, Id, i ) + if ( Abc_InfoHasBit((unsigned *)Cec5_ObjSim(p, Id), iPat) ) + Abc_InfoSetBit( pCex->pData, i ); + return pCex; +} +int Cec5_ManSimulateCos( Gia_Man_t * p ) +{ + int i, Id; + // check outputs and generate CEX if they fail + Gia_ManForEachCoId( p, Id, i ) + { + Cec5_ObjSimCo( p, Id ); + if ( Cec5_ObjSimEqual(p, Id, 0) ) + continue; + p->pCexSeq = Cec5_ManDeriveCex( p, i, Abc_TtFindFirstBit2(Cec5_ObjSim(p, Id), p->nSimWords) ); + return 0; + } + return 1; +} +void Cec5_ManSimulate( Gia_Man_t * p, Cec5_Man_t * pMan ) +{ + abctime clk = Abc_Clock(); + Gia_Obj_t * pObj; int i; + pMan->nSimulates++; + if ( pMan->pTable == NULL ) + Cec5_RefineInit( p, pMan ); + else + assert( Vec_IntSize(pMan->vRefClasses) == 0 ); + + pMan->simStart = pMan->simGlobalTop; + Gia_ManForEachAnd( p, pObj, i ) + { + int iRepr = Gia_ObjRepr( p, i ); + if ( Gia_ObjIsXor(pObj) ) + Cec5_ObjSimXor( p, pMan, i ); + else + Cec5_ObjSimAnd( p, pMan, i ); + if ( iRepr == GIA_VOID || p->pReprs[iRepr].fColorA || Cec5_ObjSimEqual(p, iRepr, i) ) + continue; + p->pReprs[iRepr].fColorA = 1; + Vec_IntPush( pMan->vRefClasses, iRepr ); + } + pMan->simStart = 0; + pMan->timeSim += Abc_Clock() - clk; + clk = Abc_Clock(); + Cec5_RefineClasses( p, pMan, pMan->vRefClasses ); + pMan->timeRefine += Abc_Clock() - clk; +} +void Cec5_ManSimulate_rec( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj ) +{ + Gia_Obj_t * pObj; + int progress; + if ( !iObj || (progress = Vec_IntEntry(pMan->vCexStamps, iObj)) == pMan->simTravId ) + return; + Vec_IntWriteEntry( pMan->vCexStamps, iObj, pMan->simTravId ); + pObj = Gia_ManObj(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Cec5_ManSimulate_rec( p, pMan, Gia_ObjFaninId0(pObj, iObj) ); + Cec5_ManSimulate_rec( p, pMan, Gia_ObjFaninId1(pObj, iObj) ); + pMan->simStart = progress * pMan->LocalBatchSize / (sizeof(word)<<3); + if ( Gia_ObjIsXor(pObj) ) + Cec5_ObjSimXor( p, pMan, iObj ); + else + Cec5_ObjSimAnd( p, pMan, iObj ); + pMan->simStart = 0; +} +void Cec5_ManSimAlloc( Gia_Man_t * p, int nWords, int fPrep ) +{ + if( !fPrep ){ + Vec_WrdFreeP( &p->vSimsPi ); + p->vSimsPi = Vec_WrdStart( (Gia_ManCiNum(p) + 1) * nWords ); + } + Vec_WrdFreeP( &p->vSims ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->nSimWords = nWords; +} + + +/**Function************************************************************* + + Synopsis [Creating initial equivalence classes.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec5_ManPrintTfiConeStats( Gia_Man_t * p ) +{ + Vec_Int_t * vRoots = Vec_IntAlloc( 100 ); + Vec_Int_t * vNodes = Vec_IntAlloc( 100 ); + Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); + int i, k; + Gia_ManForEachClass0( p, i ) + { + Vec_IntClear( vRoots ); + if ( i % 100 != 0 ) + continue; + Vec_IntPush( vRoots, i ); + Gia_ClassForEachObj1( p, i, k ) + Vec_IntPush( vRoots, k ); + Gia_ManCollectTfi( p, vRoots, vNodes ); + printf( "Class %6d : ", i ); + printf( "Roots = %6d ", Vec_IntSize(vRoots) ); + printf( "Nodes = %6d ", Vec_IntSize(vNodes) ); + printf( "\n" ); + } + Vec_IntFree( vRoots ); + Vec_IntFree( vNodes ); + Vec_IntFree( vLeaves ); +} +void Cec5_ManPrintStats( Gia_Man_t * p, Cec_ParFra_t * pPars, Cec5_Man_t * pMan, int fSim ) +{ + static abctime clk = 0; + abctime clkThis = 0; + int i, nLits, Counter = 0, Counter0 = 0, CounterX = 0; + if ( !pPars->fVerbose ) + return; + if ( pMan->nItersSim + pMan->nItersSat ) + clkThis = Abc_Clock() - clk; + clk = Abc_Clock(); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + { + if ( Gia_ObjIsHead(p, i) ) + Counter++; + else if ( Gia_ObjIsConst(p, i) ) + Counter0++; + else if ( Gia_ObjIsNone(p, i) ) + CounterX++; + } + nLits = Gia_ManObjNum(p) - Counter - CounterX; + if ( fSim ) + { + printf( "Sim %4d : ", pMan->nItersSim++ + pMan->nItersSat ); + printf( "%6.2f %% ", 100.0*nLits/Gia_ManCandNum(p) ); + } + else + { + printf( "SAT %4d : ", pMan->nItersSim + pMan->nItersSat++ ); + printf( "%6.2f %% ", 100.0*pMan->nAndNodes/Gia_ManAndNum(p) ); + } + printf( "P =%7d ", pMan ? pMan->nSatUnsat : 0 ); + printf( "D =%7d ", pMan ? pMan->nSatSat : 0 ); + printf( "F =%8d ", pMan ? pMan->nSatUndec : 0 ); + //printf( "Last =%6d ", pMan ? pMan->iLastConst : 0 ); + Abc_Print( 1, "cst =%9d cls =%8d lit =%9d ", Counter0, Counter, nLits ); + Abc_PrintTime( 1, "Time", clkThis ); +} +void Cec5_ManPrintClasses2( Gia_Man_t * p ) +{ + int i, k; + Gia_ManForEachClass0( p, i ) + { + printf( "Class %d : ", i ); + Gia_ClassForEachObj1( p, i, k ) + printf( "%d ", k ); + printf( "\n" ); + } +} +void Cec5_ManPrintClasses( Gia_Man_t * p ) +{ + int k, Count = 0; + Gia_ClassForEachObj1( p, 0, k ) + Count++; + printf( "Const0 class has %d entries.\n", Count ); +} + + +/**Function************************************************************* + + Synopsis [Verify counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec5_ManVerify_rec( Gia_Man_t * p, int iObj, sat_solver * pSat ) +{ + int Value0, Value1; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( iObj == 0 ) return 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return pObj->fMark1; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return pObj->fMark1 = sat_solver_read_cex_varvalue(pSat, Cec5_ObjSatId(p, pObj)); + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Cec5_ManVerify_rec( p, Gia_ObjFaninId0(pObj, iObj), pSat ) ^ Gia_ObjFaninC0(pObj); + Value1 = Cec5_ManVerify_rec( p, Gia_ObjFaninId1(pObj, iObj), pSat ) ^ Gia_ObjFaninC1(pObj); + return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1; +} +void Cec5_ManVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase, sat_solver * pSat ) +{ + int Value0, Value1; + Gia_ManIncrementTravId( p ); + Value0 = Cec5_ManVerify_rec( p, iObj0, pSat ); + Value1 = Cec5_ManVerify_rec( p, iObj1, pSat ); + if ( (Value0 ^ Value1) == fPhase ) + printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 ); +// else +// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );; +} + + +/**Function************************************************************* + + Synopsis [Verify counter-example.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cec5_ManCexVerify_rec( Gia_Man_t * p, int iObj ) +{ + int Value0, Value1; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + if ( iObj == 0 ) return 0; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return pObj->fMark1; + Gia_ObjSetTravIdCurrentId(p, iObj); + if ( Gia_ObjIsCi(pObj) ) + return pObj->fMark1 = Cec5_ObjSimGetInputBit(p, iObj); + assert( Gia_ObjIsAnd(pObj) ); + Value0 = Cec5_ManCexVerify_rec( p, Gia_ObjFaninId0(pObj, iObj) ) ^ Gia_ObjFaninC0(pObj); + Value1 = Cec5_ManCexVerify_rec( p, Gia_ObjFaninId1(pObj, iObj) ) ^ Gia_ObjFaninC1(pObj); + return pObj->fMark1 = Gia_ObjIsXor(pObj) ? Value0 ^ Value1 : Value0 & Value1; +} +void Cec5_ManCexVerify( Gia_Man_t * p, int iObj0, int iObj1, int fPhase ) +{ + int Value0, Value1; + Gia_ManIncrementTravId( p ); + Value0 = Cec5_ManCexVerify_rec( p, iObj0 ); + Value1 = Cec5_ManCexVerify_rec( p, iObj1 ); + if ( (Value0 ^ Value1) == fPhase ) + printf( "CEX verification FAILED for obj %d and obj %d.\n", iObj0, iObj1 ); +// else +// printf( "CEX verification succeeded for obj %d and obj %d.\n", iObj0, iObj1 );; +} + +/**Function************************************************************* + + Synopsis [Packs simulation patterns into array of simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +*************************************`**********************************/ +void Cec5_ManPackAddPatterns( Gia_Man_t * p, int iBit, Vec_Int_t * vLits ) +{ + int k, Limit = Abc_MinInt( Vec_IntSize(vLits), 64 * p->nSimWords - 1 ); + for ( k = 0; k < Limit; k++ ) + { + int i, Lit, iBitLocal = (iBit + k + 1) % Limit + 1; + assert( iBitLocal > 0 && iBitLocal < 64 * p->nSimWords ); + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) ); + word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) ); + if ( Abc_InfoHasBit( (unsigned *)pPres, iBitLocal ) ) + continue; + if ( Abc_InfoHasBit( (unsigned *)pInfo, iBitLocal ) != Abc_LitIsCompl(Lit ^ (i == k)) ) + Abc_InfoXorBit( (unsigned *)pInfo, iBitLocal ); + } + } +} +int Cec5_ManPackAddPatternTry( Gia_Man_t * p, int iBit, Vec_Int_t * vLits ) +{ + int i, Lit; + assert( p->iPatsPi > 0 && p->iPatsPi < 64 * p->nSimWords ); + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) ); + word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) ); + if ( Abc_InfoHasBit( (unsigned *)pPres, iBit ) && + Abc_InfoHasBit( (unsigned *)pInfo, iBit ) != Abc_LitIsCompl(Lit) ) + return 0; + } + Vec_IntForEachEntry( vLits, Lit, i ) + { + word * pInfo = Vec_WrdEntryP( p->vSims, p->nSimWords * Abc_Lit2Var(Lit) ); + word * pPres = Vec_WrdEntryP( p->vSimsPi, p->nSimWords * Abc_Lit2Var(Lit) ); + Abc_InfoSetBit( (unsigned *)pPres, iBit ); + if ( Abc_InfoHasBit( (unsigned *)pInfo, iBit ) != Abc_LitIsCompl(Lit) ) + Abc_InfoXorBit( (unsigned *)pInfo, iBit ); + } + return 1; +} +int Cec5_ManPackAddPattern( Gia_Man_t * p, Vec_Int_t * vLits, int fExtend ) +{ + int k; + for ( k = 1; k < 64 * p->nSimWords - 1; k++ ) + { + if ( ++p->iPatsPi == 64 * p->nSimWords - 1 ) + p->iPatsPi = 1; + if ( Cec5_ManPackAddPatternTry( p, p->iPatsPi, vLits ) ) + { + if ( fExtend ) + Cec5_ManPackAddPatterns( p, p->iPatsPi, vLits ); + break; + } + } + if ( k == 64 * p->nSimWords - 1 ) + { + p->iPatsPi = k; + if ( !Cec5_ManPackAddPatternTry( p, p->iPatsPi, vLits ) ) + printf( "Internal error.\n" ); + else if ( fExtend ) + Cec5_ManPackAddPatterns( p, p->iPatsPi, vLits ); + return 64 * p->nSimWords; + } + return k; +} + +/**Function************************************************************* + + Synopsis [Generates counter-examples to refine the candidate equivalences.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Cec5_ObjFan0IsAssigned( Gia_Obj_t * pObj ) +{ + return Gia_ObjFanin0(pObj)->fMark0 || Gia_ObjFanin0(pObj)->fMark1; +} +static inline int Cec5_ObjFan1IsAssigned( Gia_Obj_t * pObj ) +{ + return Gia_ObjFanin1(pObj)->fMark0 || Gia_ObjFanin1(pObj)->fMark1; +} +static inline int Cec5_ObjFan0HasValue( Gia_Obj_t * pObj, int v ) +{ + return (v ^ Gia_ObjFaninC0(pObj)) ? Gia_ObjFanin0(pObj)->fMark1 : Gia_ObjFanin0(pObj)->fMark0; +} +static inline int Cec5_ObjFan1HasValue( Gia_Obj_t * pObj, int v ) +{ + return (v ^ Gia_ObjFaninC1(pObj)) ? Gia_ObjFanin1(pObj)->fMark1 : Gia_ObjFanin1(pObj)->fMark0; +} +static inline int Cec5_ObjObjIsImpliedValue( Gia_Obj_t * pObj, int v ) +{ + assert( !pObj->fMark0 && !pObj->fMark1 ); // not visited + if ( v ) + return Cec5_ObjFan0HasValue(pObj, 1) && Cec5_ObjFan1HasValue(pObj, 1); + return Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0); +} +static inline int Cec5_ObjFan0IsImpliedValue( Gia_Obj_t * pObj, int v ) +{ + return Gia_ObjIsAnd(Gia_ObjFanin0(pObj)) && Cec5_ObjObjIsImpliedValue( Gia_ObjFanin0(pObj), v ^ Gia_ObjFaninC0(pObj) ); +} +static inline int Cec5_ObjFan1IsImpliedValue( Gia_Obj_t * pObj, int v ) +{ + return Gia_ObjIsAnd(Gia_ObjFanin1(pObj)) && Cec5_ObjObjIsImpliedValue( Gia_ObjFanin1(pObj), v ^ Gia_ObjFaninC1(pObj) ); +} +int Cec5_ManGeneratePatterns_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, Vec_Int_t * vPat, Vec_Int_t * vVisit ) +{ + Gia_Obj_t * pFan0, * pFan1; + assert( !pObj->fMark0 && !pObj->fMark1 ); // not visited + if ( Value ) pObj->fMark1 = 1; else pObj->fMark0 = 1; + Vec_IntPush( vVisit, Gia_ObjId(p, pObj) ); + if ( Gia_ObjIsCi(pObj) ) + { + Vec_IntPush( vPat, Abc_Var2Lit(Gia_ObjId(p, pObj), Value) ); + return 1; + } + assert( Gia_ObjIsAnd(pObj) ); + pFan0 = Gia_ObjFanin0(pObj); + pFan1 = Gia_ObjFanin1(pObj); + if ( Gia_ObjIsXor(pObj) ) + { + int Ass0 = Cec5_ObjFan0IsAssigned(pObj); + int Ass1 = Cec5_ObjFan1IsAssigned(pObj); + assert( Gia_ObjFaninC0(pObj) == 0 && Gia_ObjFaninC1(pObj) == 0 ); + if ( Ass0 && Ass1 ) + return Value == (Cec5_ObjFan0HasValue(pObj, 1) ^ Cec5_ObjFan1HasValue(pObj, 1)); + if ( Ass0 ) + { + int ValueInt = Value ^ Cec5_ObjFan0HasValue(pObj, 1); + if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, ValueInt, vPat, vVisit) ) + return 0; + } + else if ( Ass1 ) + { + int ValueInt = Value ^ Cec5_ObjFan1HasValue(pObj, 1); + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, ValueInt, vPat, vVisit) ) + return 0; + } + else if ( Abc_Random(0) & 1 ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, 0, vPat, vVisit) ) + return 0; + if ( Cec5_ObjFan1HasValue(pObj, !Value) || (!Cec5_ObjFan1HasValue(pObj, Value) && !Cec5_ManGeneratePatterns_rec(p, pFan1, Value, vPat, vVisit)) ) + return 0; + } + else + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, 1, vPat, vVisit) ) + return 0; + if ( Cec5_ObjFan1HasValue(pObj, Value) || (!Cec5_ObjFan1HasValue(pObj, !Value) && !Cec5_ManGeneratePatterns_rec(p, pFan1, !Value, vPat, vVisit)) ) + return 0; + } + assert( Value == (Cec5_ObjFan0HasValue(pObj, 1) ^ Cec5_ObjFan1HasValue(pObj, 1)) ); + return 1; + } + else if ( Value ) + { + if ( Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0) ) + return 0; + if ( !Cec5_ObjFan0HasValue(pObj, 1) && !Cec5_ManGeneratePatterns_rec(p, pFan0, !Gia_ObjFaninC0(pObj), vPat, vVisit) ) + return 0; + if ( !Cec5_ObjFan1HasValue(pObj, 1) && !Cec5_ManGeneratePatterns_rec(p, pFan1, !Gia_ObjFaninC1(pObj), vPat, vVisit) ) + return 0; + assert( Cec5_ObjFan0HasValue(pObj, 1) && Cec5_ObjFan1HasValue(pObj, 1) ); + return 1; + } + else + { + if ( Cec5_ObjFan0HasValue(pObj, 1) && Cec5_ObjFan1HasValue(pObj, 1) ) + return 0; + if ( Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0) ) + return 1; + if ( Cec5_ObjFan0HasValue(pObj, 1) ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) ) + return 0; + } + else if ( Cec5_ObjFan1HasValue(pObj, 1) ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) ) + return 0; + } + else + { + if ( Cec5_ObjFan0IsImpliedValue( pObj, 0 ) ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) ) + return 0; + } + else if ( Cec5_ObjFan1IsImpliedValue( pObj, 0 ) ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) ) + return 0; + } + else if ( Cec5_ObjFan0IsImpliedValue( pObj, 1 ) ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) ) + return 0; + } + else if ( Cec5_ObjFan1IsImpliedValue( pObj, 1 ) ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) ) + return 0; + } + else if ( Abc_Random(0) & 1 ) + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan1, Gia_ObjFaninC1(pObj), vPat, vVisit) ) + return 0; + } + else + { + if ( !Cec5_ManGeneratePatterns_rec(p, pFan0, Gia_ObjFaninC0(pObj), vPat, vVisit) ) + return 0; + } + } + assert( Cec5_ObjFan0HasValue(pObj, 0) || Cec5_ObjFan1HasValue(pObj, 0) ); + return 1; + } +} +int Cec5_ManGeneratePatternOne( Gia_Man_t * p, int iRepr, int iReprVal, int iCand, int iCandVal, Vec_Int_t * vPat, Vec_Int_t * vVisit ) +{ + int Res, k; + Gia_Obj_t * pObj; + assert( iCand > 0 ); + if ( !iRepr && iReprVal ) + return 0; + Vec_IntClear( vPat ); + Vec_IntClear( vVisit ); + //Gia_ManForEachObj( p, pObj, k ) + // assert( !pObj->fMark0 && !pObj->fMark1 ); + Res = (!iRepr || Cec5_ManGeneratePatterns_rec(p, Gia_ManObj(p, iRepr), iReprVal, vPat, vVisit)) && Cec5_ManGeneratePatterns_rec(p, Gia_ManObj(p, iCand), iCandVal, vPat, vVisit); + Gia_ManForEachObjVec( vVisit, p, pObj, k ) + pObj->fMark0 = pObj->fMark1 = 0; + return Res; +} +void Cec5_ManCandIterStart( Cec5_Man_t * p ) +{ + int i, * pArray; + assert( p->iPosWrite == 0 ); + assert( p->iPosRead == 0 ); + assert( Vec_IntSize(p->vCands) == 0 ); + for ( i = 1; i < Gia_ManObjNum(p->pAig); i++ ) + if ( Gia_ObjRepr(p->pAig, i) != GIA_VOID ) + Vec_IntPush( p->vCands, i ); + pArray = Vec_IntArray( p->vCands ); + for ( i = 0; i < Vec_IntSize(p->vCands); i++ ) + { + int iNew = Abc_Random(0) % Vec_IntSize(p->vCands); + ABC_SWAP( int, pArray[i], pArray[iNew] ); + } +} +int Cec5_ManCandIterNext( Cec5_Man_t * p ) +{ + while ( Vec_IntSize(p->vCands) > 0 ) + { + int fStop, iCand = Vec_IntEntry( p->vCands, p->iPosRead ); + if ( (fStop = (Gia_ObjRepr(p->pAig, iCand) != GIA_VOID)) ) + Vec_IntWriteEntry( p->vCands, p->iPosWrite++, iCand ); + if ( ++p->iPosRead == Vec_IntSize(p->vCands) ) + { + Vec_IntShrink( p->vCands, p->iPosWrite ); + p->iPosWrite = 0; + p->iPosRead = 0; + } + if ( fStop ) + return iCand; + } + return 0; +} +int Cec5_ManGeneratePatterns( Cec5_Man_t * p ) +{ + abctime clk = Abc_Clock(); + int i, iCand, nPats = 100 * 64 * p->pAig->nSimWords, CountPat = 0, Packs = 0; + //int iRepr; + //Vec_IntForEachEntryDouble( p->vDisprPairs, iRepr, iCand, i ) + // if ( iRepr == Gia_ObjRepr(p->pAig, iCand) ) + // printf( "Pair %6d (%6d, %6d) (new repr = %9d) is FAILED to disprove.\n", i, iRepr, iCand, Gia_ObjRepr(p->pAig, iCand) ); + // else + // printf( "Pair %6d (%6d, %6d) (new repr = %9d) is disproved.\n", i, iRepr, iCand, Gia_ObjRepr(p->pAig, iCand) ); + //Vec_IntClear( p->vDisprPairs ); + p->pAig->iPatsPi = 0; + Vec_WrdFill( p->pAig->vSimsPi, Vec_WrdSize(p->pAig->vSimsPi), 0 ); + for ( i = 0; i < nPats; i++ ) + if ( (iCand = Cec5_ManCandIterNext(p)) ) + { + int iRepr = Gia_ObjRepr( p->pAig, iCand ); + int iCandVal = Gia_ManObj(p->pAig, iCand)->fPhase; + int iReprVal = Gia_ManObj(p->pAig, iRepr)->fPhase; + int Res = Cec5_ManGeneratePatternOne( p->pAig, iRepr, iReprVal, iCand, !iCandVal, p->vPat, p->vVisit ); + if ( !Res ) + Res = Cec5_ManGeneratePatternOne( p->pAig, iRepr, !iReprVal, iCand, iCandVal, p->vPat, p->vVisit ); + if ( Res ) + { + int Ret = Cec5_ManPackAddPattern( p->pAig, p->vPat, 1 ); + if ( p->pAig->vPats ) + { + Vec_IntPush( p->pAig->vPats, Vec_IntSize(p->vPat)+2 ); + Vec_IntAppend( p->pAig->vPats, p->vPat ); + Vec_IntPush( p->pAig->vPats, -1 ); + } + //Vec_IntPushTwo( p->vDisprPairs, iRepr, iCand ); + Packs += Ret; + if ( 0 == (Ret % (64 * p->pAig->nSimWords / p->simBatchFactor)) ) + break; + if ( ++CountPat == 8 * 64 * p->pAig->nSimWords ) + break; + //Cec5_ManCexVerify( p->pAig, iRepr, iCand, iReprVal ^ iCandVal ); + //Gia_ManCleanMark01( p->pAig ); + } + } + p->timeGenPats += Abc_Clock() - clk; + p->nSatSat += CountPat; + //printf( "%3d : %6.2f %% : Generated %6d CEXs after trying %6d pairs. Ave packs = %9.2f Ave tries = %9.2f (Limit = %9.2f)\n", + // p->nItersSim++, 100.0*Vec_IntSize(p->vCands)/Gia_ManAndNum(p->pAig), + // CountPat, i, (float)Packs / Abc_MaxInt(1, CountPat), (float)i / Abc_MaxInt(1, CountPat), (float)nPats / p->pPars->nItersMax ); + return CountPat >= i / p->pPars->nItersMax; +} + + +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec5_ManSatSolverRecycle( Cec5_Man_t * p ) +{ + Gia_Obj_t * pObj; + int i; + //printf( "Solver size = %d.\n", sat_solver_varnum(p->pSat) ); + if( p->adaRecycle && p->adaRecycle < p->nConflicts[2][2] ) + return; + p->nRecycles++; + p->nCallsSince = 0; + sat_solver_reset( p->pSat ); + // clean mapping of AigIds into SatIds + Gia_ManForEachObjVec( &p->pNew->vSuppVars, p->pNew, pObj, i ) + Cec5_ObjCleanSatId( p->pNew, pObj ); + Vec_IntClear( &p->pNew->vSuppVars ); // AigIds for which SatId is defined + Vec_IntClear( &p->pNew->vCopiesTwo ); // pairs (CiAigId, SatId) + Vec_IntClear( &p->pNew->vVarMap ); // mapping of SatId into AigId +} +void Cec5_ManLoadInstance( Cec5_Man_t * p, int iObj0, int iObj1, int * piVar0, int * piVar1 ){ + int iVar0 = Cec5_ObjGetCnfVar( p, iObj0 ); + int iVar1 = Cec5_ObjGetCnfVar( p, iObj1 ); + if( p->pPars->jType > 0 ) + { + extern void glucose2_markapprox( void * pSat, int v0, int v1, int nlim ); + int nlim = p->approxLim; + glucose2_markapprox( p->pSat, iVar0, iVar1, nlim ); + } + + * piVar0 = iVar0; + * piVar1 = iVar1; +} + +int Cec5_ManSolveTwo( Cec5_Man_t * p, int iObj0, int iObj1, int fPhase, int * pfEasy, int fVerbose, int fEffort ) +{ + abctime clk; + int nBTLimit = fEffort ? p->pPars->nBTLimitPo : (Vec_BitEntry(p->vFails, iObj0) || Vec_BitEntry(p->vFails, iObj1)) ? Abc_MaxInt(1, p->pPars->nBTLimit/10) : p->pPars->nBTLimit; + int nConfEnd, nConfBeg, status, iVar0, iVar1, Lits[2]; + int UnsatConflicts[3] = {0}; + //printf( "%d ", nBTLimit ); + if ( iObj1 < iObj0 ) + iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; + assert( iObj0 < iObj1 ); + *pfEasy = 0; + // check if SAT solver needs recycling + p->nCallsSince++; + if ( p->nCallsSince > p->pPars->nCallsRecycle && + Vec_IntSize(&p->pNew->vSuppVars) > p->pPars->nSatVarMax && p->pPars->nSatVarMax ) + Cec5_ManSatSolverRecycle( p ); + // add more logic to the solver + if ( !iObj0 && Cec5_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 ) + Cec5_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), sat_solver_addvar(p->pSat) ); + clk = Abc_Clock(); + Cec5_ManLoadInstance( p, iObj0, iObj1, &iVar0, &iVar1); + p->timeCnf += Abc_Clock() - clk; + // perform solving + Lits[0] = Abc_Var2Lit(iVar0, 1); + Lits[1] = Abc_Var2Lit(iVar1, fPhase); + sat_solver_set_conflict_budget( p->pSat, nBTLimit ); + nConfBeg = sat_solver_conflictnum( p->pSat ); + status = sat_solver_solve( p->pSat, Lits, 2 ); + nConfEnd = sat_solver_conflictnum( p->pSat ); + assert( nConfEnd >= nConfBeg ); + p->nConflicts[2][2] = Abc_MaxInt(p->nConflicts[2][2], nConfEnd - nConfBeg); + if ( fVerbose ) + { + if ( status == GLUCOSE_SAT ) + { + p->nConflicts[0][0] += nConfEnd == nConfBeg; + p->nConflicts[0][1] += nConfEnd - nConfBeg; + p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + else if ( status == GLUCOSE_UNSAT ) + { + if ( iObj0 > 0 ) + { + UnsatConflicts[0] = nConfEnd == nConfBeg; + UnsatConflicts[1] = nConfEnd - nConfBeg; + UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]); + } + else + { + p->nConflicts[1][0] += nConfEnd == nConfBeg; + p->nConflicts[1][1] += nConfEnd - nConfBeg; + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + } + } + if ( status == GLUCOSE_UNSAT && iObj0 > 0 ) + { + Lits[0] = Abc_Var2Lit(iVar0, 0); + Lits[1] = Abc_Var2Lit(iVar1, !fPhase); + sat_solver_set_conflict_budget( p->pSat, nBTLimit ); + nConfBeg = sat_solver_conflictnum( p->pSat ); + status = sat_solver_solve( p->pSat, Lits, 2 ); + nConfEnd = sat_solver_conflictnum( p->pSat ); + assert( nConfEnd >= nConfBeg ); + p->nConflicts[2][2] = Abc_MaxInt(p->nConflicts[2][2], nConfEnd - nConfBeg); + if ( fVerbose ) + { + if ( status == GLUCOSE_SAT ) + { + p->nConflicts[0][0] += nConfEnd == nConfBeg; + p->nConflicts[0][1] += nConfEnd - nConfBeg; + p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + else if ( status == GLUCOSE_UNSAT ) + { + UnsatConflicts[0] &= nConfEnd == nConfBeg; + UnsatConflicts[1] += nConfEnd - nConfBeg; + UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + + p->nConflicts[1][0] += UnsatConflicts[0]; + p->nConflicts[1][1] += UnsatConflicts[1]; + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]); + *pfEasy = UnsatConflicts[0]; + } + } + } + //if ( status == GLUCOSE_UNDEC ) + // printf( "* " ); + return status; +} +void Cec5_FlushCache2Pattern( Cec5_Man_t * p ){ + int j, iLit, nWrite = 0; + int iPatsOld = p->pAig->iPatsPi; + j = 0; + p->pAig->iPatsPi -- ; + while( j < p->vPiPatsCache->nSize ){ + if( -1 < (iLit = p->vPiPatsCache->pArray[j++]) ){ + Cec5_ObjSimSetInputBit( p->pAig, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) ); + continue; + } + p->pAig->iPatsPi -- ; + nWrite ++ ; + } + p->pAig->iPatsPi += nWrite+1; + assert( iPatsOld == p->pAig->iPatsPi ); + p->vPiPatsCache->nSize = 0; +} +void Cec5_ClearCexMarks( Cec5_Man_t * p ){ + Vec_IntFill( p->vCexStamps, Gia_ManObjNum(p->pAig), 0 ); + Vec_BitFill( p->vCexSite , Gia_ManObjNum(p->pAig), 0 ); +} +void Cec5_ManCheckGlobalSim( Cec5_Man_t * p){ + int iPatTop = p->pAig->iPatsPi; + if ( (iPatTop % (sizeof(word) * 8 * p->pAig->nSimWords / p->simBatchFactor)) == 0 + || iPatTop == (int)sizeof(word) * 8 * p->pAig->nSimWords - 2 ) + { + abctime clk2 = Abc_Clock(); + Cec5_FlushCache2Pattern(p); + //p->simBound = iPatTop / (sizeof(word) * 8 * p->pAig->nSimWords / p->simBatchFactor)+2;//p->simTravId * p->LocalBatchSize / (sizeof(word) * 8<<3)+1; + p->simBound = iPatTop / (sizeof(word) * 8) + ((iPatTop % (sizeof(word) * 8)) ? 1: 0); + //if( iPatTop == sizeof(word) * 8 * p->pAig->nSimWords - 2 ) + // p->simBound += 1; + //printf("re-sim %5d %5d bound %5d\n", p->pAig->iPatsPi, p->simTravId, p->simBound ); + Cec5_ManSimulate( p->pAig, p ); + p->simBound = p->pPars->nWords; + //printf( "FasterSmall = %d. FasterBig = %d.\n", p->nFaster[0], p->nFaster[1] ); + p->nFaster[0] = p->nFaster[1] = 0; + //if ( p->nSatSat && p->nSatSat % 100 == 0 ) + //Cec5_ManPrintStats( p->pAig, p->pPars, p, 0 ); + Cec5_ClearCexMarks(p); + if( iPatTop == (int)sizeof(word) * 8 * p->pAig->nSimWords - 2 ){ + Cec5_ManPrintStats( p->pAig, p->pPars, p, 0 ); + p->pAig->iPatsPi = 0; + p->simTravId = 0; + p->simGlobalTop = 0; + } else { + //assert( 0 == iPatTop % (sizeof(word) * 8 * p->pAig->nSimWords) ); + p->pAig->iPatsPi = iPatTop; + p->simGlobalTop = iPatTop / (sizeof(word) * 8 ); + } + Vec_WrdFill( p->pAig->vSimsPi, Vec_WrdSize(p->pAig->vSimsPi), 0 ); + p->timeResimGlo += Abc_Clock() - clk2; + } +} +int Cec5_ManSweepNode( Cec5_Man_t * p, int iObj, int iRepr ) +{ + abctime clk = Abc_Clock(); + int i, IdAig, IdSat, status, fEasy, RetValue = 1; + Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); + Gia_Obj_t * pRepr = Gia_ManObj( p->pAig, iRepr ); + int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase; + int fEffort = p->vCoDrivers ? Vec_BitEntry(p->vCoDrivers, iObj) || Vec_BitEntry(p->vCoDrivers, iRepr) : 0; + status = Cec5_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort ); + if ( status == GLUCOSE_SAT ) + { + int iLit; + Vec_BitWriteEntry( p->vCexSite, iObj, 1 ); + //int iPatsOld = p->pAig->iPatsPi; + //printf( "Disproved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) ); + p->nSatSat++; + p->nPatterns++; + Vec_IntClear( p->vPat ); + if ( p->pPars->jType == 0 ) + { + Vec_IntForEachEntryDouble( &p->pNew->vCopiesTwo, IdAig, IdSat, i ) + Vec_IntPush( p->vPat, Abc_Var2Lit(IdAig, sat_solver_read_cex_varvalue(p->pSat, IdSat)) ); + } + else + { + int * pCex = sat_solver_read_cex( p->pSat ); + int * pMap = Vec_IntArray(&p->pNew->vVarMap); + for ( i = 0; i < pCex[0]; ) + Vec_IntPush( p->vPat, Abc_Lit2LitV(pMap, Abc_LitNot(pCex[++i])) ); + } + assert( p->pAig->iPatsPi >= 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords - 1 ); + p->pAig->iPatsPi++; +// Vec_IntForEachEntry( p->vPat, iLit, i ) +// Cec5_ObjSimSetInputBit( p->pAig, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) ); + Vec_IntForEachEntry( p->vPat, iLit, i ) + Vec_IntPush( p->vPiPatsCache, iLit ); + Vec_IntPush( p->vPiPatsCache, -1 ); + if ( p->pAig->vPats ) + { + Vec_IntPush( p->pAig->vPats, Vec_IntSize(p->vPat)+2 ); + Vec_IntAppend( p->pAig->vPats, p->vPat ); + Vec_IntPush( p->pAig->vPats, -1 ); + } + //Cec5_ManPackAddPattern( p->pAig, p->vPat, 0 ); + //assert( iPatsOld + 1 == p->pAig->iPatsPi ); + if ( fEasy ) + p->timeSatSat0 += Abc_Clock() - clk; + else + p->timeSatSat += Abc_Clock() - clk; + RetValue = 0; + + p->simTravId = p->pAig->iPatsPi / p->LocalBatchSize; + if( (p->pAig->iPatsPi % p->LocalBatchSize) == 0 || 1 == p->LocalBatchSize ) + Cec5_FlushCache2Pattern(p); + + // this is not needed, but we keep it here anyway, because it takes very little time + //Cec5_ManVerify( p->pNew, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, p->pSat ); + // resimulated once in a while + //if ( p->pAig->iPatsPi == 64 * p->pAig->nSimWords - 2 ) + Cec5_ManCheckGlobalSim(p); + } + else if ( status == GLUCOSE_UNSAT ) + { + //printf( "Proved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) ); + p->nSatUnsat++; + pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); + assert( !Gia_ObjProved( p->pAig, iObj ) ); + Gia_ObjSetProved( p->pAig, iObj ); + if ( iRepr == 0 ) + p->iLastConst = iObj; + if ( fEasy ) + p->timeSatUnsat0 += Abc_Clock() - clk; + else + p->timeSatUnsat += Abc_Clock() - clk; + RetValue = 1; + } + else + { + p->nSatUndec++; + assert( status == GLUCOSE_UNDEC ); + Gia_ObjSetFailed( p->pAig, iObj ); + Vec_BitWriteEntry( p->vFails, iObj, 1 ); + //if ( iRepr ) + //Vec_BitWriteEntry( p->vFails, iRepr, 1 ); + p->timeSatUndec += Abc_Clock() - clk; + RetValue = 2; + } + return RetValue; +} +Gia_Obj_t * Cec5_ManFindRepr( Gia_Man_t * p, Cec5_Man_t * pMan, int iObj ) +{ + abctime clk = Abc_Clock(); + Gia_Obj_t * pRepr = NULL; + int iMem, iRepr; + assert( Gia_ObjHasRepr(p, iObj) ); + assert( !Gia_ObjProved(p, iObj) ); + iRepr = Gia_ObjRepr(p, iObj); + assert( iRepr != iObj ); + assert( !Gia_ObjProved(p, iRepr) ); + + pMan->simBound = pMan->simTravId * pMan->LocalBatchSize / (sizeof(word)<<3)+1; + assert( pMan->simBound <= pMan->pPars->nWords ); + + if( (Vec_BitEntry( pMan->vCexSite, iObj ) | Vec_BitEntry( pMan->vCexSite, iRepr )) + ||(Vec_IntEntry( pMan->vCexStamps, iObj ) != Vec_IntEntry( pMan->vCexStamps, iRepr )) ){ + Cec5_ManSimulate_rec( p, pMan, iObj ); + Cec5_ManSimulate_rec( p, pMan, iRepr ); + } + if ( Cec5_ObjSimEqual(p, iObj, iRepr) ) + { + pMan->timeResimLoc += Abc_Clock() - clk; + pRepr = Gia_ManObj(p, iRepr); + goto finalize; + } + Gia_ClassForEachObj1( p, iRepr, iMem ) + { + if ( iObj == iMem ) + break; + assert(iMemvCexStamps, iObj ) != Vec_IntEntry( pMan->vCexStamps, iMem ) ){ + Cec5_ManSimulate_rec( p, pMan, iMem ); + Cec5_ManSimulate_rec( p, pMan, iObj ); + } + if ( Cec5_ObjSimEqual(p, iObj, iMem) ) + { + pMan->nFaster[0]++; + pMan->timeResimLoc += Abc_Clock() - clk; + pRepr = Gia_ManObj(p, iMem); + goto finalize; + } + } + pMan->nFaster[1]++; + pMan->timeResimLoc += Abc_Clock() - clk; +finalize: + pMan->simBound = pMan->pPars->nWords; + return pRepr; +} +void Cec5_ManExtend( Cec5_Man_t * pMan, CbsP_Man_t * pCbs ){ + while( pMan->pNew->vCopies2.nSize < Gia_ManObjNum(pMan->pNew) ){ + Vec_IntPush( &pMan->pNew->vCopies2, -1 ); + Vec_BitPush( pMan->vFails, 0 ); + if( pCbs ) + Vec_IntPush( pCbs->vValue, ~0 ); + } +} + +int Cec5_ManSweepNodeCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj, int iRepr, int fTagFail ); +int Cec5_ManPerformSweeping( Gia_Man_t * p, Cec_ParFra_t * pPars, Gia_Man_t ** ppNew, int fSimOnly, int fCbs, int approxLim, int subBatchSz, int adaRecycle ) +{ + Gia_Obj_t * pObj, * pRepr; + CbsP_Man_t * pCbs = NULL; + int i, fSimulate = 1; + int fPrep = 0; + int AccuSat = 0; + int * vMerged; + int go_back = -1; + + Cec5_Man_t * pMan = Cec5_ManCreate( p, pPars ); + pMan->approxLim = approxLim; + if( pMan->simBatchFactor != subBatchSz ){ + printf("overwrite default batch size: from %3d to %3d\n", pMan->simBatchFactor, subBatchSz); + pMan->simBatchFactor = subBatchSz; + } + if( pMan->adaRecycle != adaRecycle ){ + printf("overwrite default adaptive recycle: from %3d to %3d\n", pMan->adaRecycle, adaRecycle); + pMan->adaRecycle = adaRecycle; + } + if ( pPars->fVerbose ) + printf( "Solver type = %d. Simulate %d words in %d rounds. SAT with %d confs. Recycle after %d SAT calls.\n", + pPars->jType, pPars->nWords, pPars->nRounds, pPars->nBTLimit, pPars->nCallsRecycle ); + + if( fPrep ) + pMan->fEec = 1; + + + // this is currently needed to have a correct mapping + Gia_ManForEachCi( p, pObj, i ) + assert( Gia_ObjId(p, pObj) == i+1 ); + + // check if any output trivially fails under all-0 pattern + Gia_ManRandom( 1 ); + Gia_ManSetPhase( p ); + if ( pPars->nLevelMax ) + Gia_ManLevelNum(p); + //Gia_ManStaticFanoutStart( p ); + if ( pPars->fCheckMiter ) + { + Gia_ManForEachCo( p, pObj, i ) + if ( pObj->fPhase ) + { + p->pCexSeq = Cec5_ManDeriveCex( p, i, -1 ); + goto finalize; + } + } + + // simulate one round and create classes + Cec5_ManSimAlloc( p, pPars->nWords, 0 ); + Cec5_ManSimulateCis( p ); + Cec5_ManSimulate( p, pMan ); + if ( pPars->fCheckMiter && !Cec5_ManSimulateCos(p) ) // cex detected + goto finalize; + if ( pPars->fVerbose ) + Cec5_ManPrintStats( p, pPars, pMan, 1 ); + + // perform simulation + for ( i = 0; i < pPars->nRounds; i++ ) + { + Cec5_ManSimulateCis( p ); + Cec5_ManSimulate( p, pMan ); + if ( pPars->fCheckMiter && !Cec5_ManSimulateCos(p) ) // cex detected + goto finalize; + if ( i && i % (pPars->nRounds / 5) == 0 && pPars->fVerbose ) + Cec5_ManPrintStats( p, pPars, pMan, 1 ); + } + if ( fSimOnly ) + goto finalize; + + + // perform additional simulation + Cec5_ManCandIterStart( pMan ); + for ( i = 0; fSimulate && i < pPars->nGenIters; i++ ) + { + Cec5_ManSimulateCis( p ); + fSimulate = Cec5_ManGeneratePatterns( pMan ); + Cec5_ManSimulate( p, pMan ); + if ( pPars->fCheckMiter && !Cec5_ManSimulateCos(p) ) // cex detected + goto finalize; + if ( i && i % 5 == 0 && pPars->fVerbose ) + Cec5_ManPrintStats( p, pPars, pMan, 1 ); + if( pMan->nSatSat - AccuSat < p->nSimWords * (int)sizeof(word) * 8 ) + break; + + AccuSat = pMan->nSatSat; + } + if ( i && i % 5 && pPars->fVerbose ) + Cec5_ManPrintStats( p, pPars, pMan, 1 ); + + vMerged = ABC_FALLOC(int, Gia_ManObjNum(p)); // refinement may move non-repr merge around . record the true merged performed + + p->iPatsPi = 0; + Vec_WrdFill( p->vSimsPi, Vec_WrdSize(p->vSimsPi), 0 ); + pMan->nSatSat = 0; + pMan->pNew = Cec5_ManStartNew( p ); + + if( fCbs ){ + //Gia_ManCreateRefs( pMan->pNew ); + pMan->pNew->pRefs = ABC_CALLOC( int, Gia_ManObjNum(p) ); + Gia_ManCleanMark0( pMan->pNew ); + Gia_ManCleanMark1( pMan->pNew ); + Gia_ManFillValue ( pMan->pNew ); + pCbs = CbsP_ManAlloc( p ); + pCbs->pAig = pMan->pNew; + pCbs->Pars.nBTLimit = 100;//pPars->nBTLimit; + pCbs->Pars.nJustLimit = 100; + pCbs->Pars.nJscanLimit = 100; + pCbs->Pars.nRscanLimit = 100; + pCbs->Pars.nPropLimit = 100; + + if( pPars->fVerbose ){ + printf("cbs: clim = %4d jlim = %4d\n" + , pCbs->Pars.nBTLimit + , pCbs->Pars.nJustLimit ); + } + } + + //Gia_ManForEachAnd( p, pObj, i ) + i = 0; +resume: + for( ; i < Gia_ManObjNum(p) && (pObj = Gia_ManObj(p,i)); i ++ ) + { + int status = 2; + Gia_Obj_t * pObjNew; + if ( !Gia_ObjIsAnd(pObj) ) + continue; + + Vec_BitWriteEntry( pMan->vCexSite, i + , Vec_BitEntry( pMan->vCexSite, Gia_ObjFaninId0(pObj,i) ) + | Vec_BitEntry( pMan->vCexSite, Gia_ObjFaninId1(pObj,i) ) ); + + if ( Gia_ObjFailed(p,i) ) + continue; + pMan->nAndNodes++; + if ( Gia_ObjProved(p, i) ){ + pRepr = Gia_ManObj( p, vMerged[i] ); + pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase ); // upate in case repr rehashed due to fanin its backtrace + continue; + } + + if ( Gia_ObjIsXor(pObj) ) + pObj->Value = Gia_ManHashXorReal( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else + pObj->Value = Gia_ManHashAnd( pMan->pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + + Cec5_ManExtend( pMan, pCbs ); + + if ( pPars->nLevelMax && Gia_ObjLevel(p, pObj) > pPars->nLevelMax ) + continue; + + pObjNew = Gia_ManObj( pMan->pNew, Abc_Lit2Var(pObj->Value) ); + if ( Gia_ObjIsAnd(pObjNew) ) + if ( Vec_BitEntry(pMan->vFails, Gia_ObjFaninId0(pObjNew, Abc_Lit2Var(pObj->Value))) || + Vec_BitEntry(pMan->vFails, Gia_ObjFaninId1(pObjNew, Abc_Lit2Var(pObj->Value))) ) + Vec_BitWriteEntry( pMan->vFails, Abc_Lit2Var(pObjNew->Value), 1 ); + //if ( Gia_ObjIsAnd(pObjNew) ) + // Gia_ObjSetAndLevel( pMan->pNew, pObjNew ); + // select representative based on candidate equivalence classes + pRepr = Gia_ObjReprObj( p, i ); + + if ( pRepr == NULL ) + continue; + + if ( 1 ) // select representative based on recent counter-examples + { + pRepr = Cec5_ManFindRepr( p, pMan, i ); + if ( pRepr == NULL ) + continue; + } + if ( Abc_Lit2Var(pObj->Value) == Abc_Lit2Var(pRepr->Value) ) + { + assert( (pObj->Value ^ pRepr->Value) == (pObj->fPhase ^ pRepr->fPhase) ); + vMerged[i] = Gia_ObjId(p, pRepr); + Gia_ObjSetProved( p, i ); + if ( Gia_ObjId(p, pRepr) == 0 ) + pMan->iLastConst = i; + + continue; + } + + if ( fCbs && (status = Cec5_ManSweepNodeCbs(pMan, pCbs, i, Gia_ObjId(p, pRepr), 0)) && Gia_ObjProved(p, i) ){ + vMerged[i] = Gia_ObjId(p, pRepr); + pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase ); + } + + if ( 2 == status && (status = Cec5_ManSweepNode(pMan, i, Gia_ObjId(p, pRepr))) && Gia_ObjProved(p, i) ){ + vMerged[i] = Gia_ObjId(p, pRepr); + pObj->Value = Abc_LitNotCond( pRepr->Value, pObj->fPhase ^ pRepr->fPhase ); + } + + if( 0 == status && -1 == go_back ) + go_back = i; + + if( 0 == pMan->nPatterns || 0!=status || pMan->nPatterns % (64 * p->nSimWords-2) ) + continue; + + if( -1 < go_back ){ + //printf("go back to %6d from %6d\n", go_back, i ); + pMan->nAndNodes -= i-go_back; + i = go_back-1, go_back = -1; + } + } + if ( p->iPatsPi > 0 ) + { + abctime clk2 = Abc_Clock(); + Cec5_FlushCache2Pattern(pMan); + Cec5_ManSimulate( p, pMan ); + p->iPatsPi = 0; + pMan->simTravId = 0; + pMan->simGlobalTop = 0; + Cec5_ClearCexMarks(pMan); + pMan->timeResimGlo += Abc_Clock() - clk2; + if( -1 < go_back ){ + i = go_back - 1; + go_back = -1; + goto resume; + } + } + + ABC_FREE(vMerged); + + if ( pPars->fVerbose ) + Cec5_ManPrintStats( p, pPars, pMan, 0 ); + if ( ppNew ) + { + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pMan->pNew, Gia_ObjFanin0Copy(pObj) ); + *ppNew = Gia_ManCleanup( pMan->pNew ); + } + + if( fCbs ){ + if ( pPars->fVerbose ){ + CbsP_ManSatPrintStats( pCbs ); + CbsP_PrintRecord(&pCbs->Pars); + } + } +finalize: + if ( pPars->fVerbose ) + printf( "SAT calls = %d: P = %d (0=%d a=%.2f m=%d) D = %d (0=%d a=%.2f m=%d) F = %d Sim = %d Recyc = %d Xor = %.2f %%\n", + pMan->nSatUnsat + pMan->nSatSat + pMan->nSatUndec, + pMan->nSatUnsat, pMan->nConflicts[1][0], (float)pMan->nConflicts[1][1]/Abc_MaxInt(1, pMan->nSatUnsat-pMan->nConflicts[1][0]), pMan->nConflicts[1][2], + pMan->nSatSat, pMan->nConflicts[0][0], (float)pMan->nConflicts[0][1]/Abc_MaxInt(1, pMan->nSatSat -pMan->nConflicts[0][0]), pMan->nConflicts[0][2], + pMan->nSatUndec, + pMan->nSimulates, pMan->nRecycles, 100.0*pMan->nGates[1]/Abc_MaxInt(1, pMan->nGates[0]+pMan->nGates[1]) ); + Cec5_ManDestroy( pMan ); + if( pCbs ) + CbsP_ManStop(pCbs); + //Gia_ManStaticFanoutStop( p ); + //Gia_ManEquivPrintClasses( p, 1, 0 ); + return p->pCexSeq ? 0 : 1; +} +Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle ) +{ + Gia_Man_t * pNew = NULL; + Cec5_ManPerformSweeping( p, pPars, &pNew, 0, fCbs, approxLim, subBatchSz, adaRecycle ); + return pNew; +} + + + +int Cec5_ManSolveTwoCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj0, int iObj1, int fPhase, int * pfEasy, int fVerbose, int fEffort ) +{ +// abctime clk; +// int nBTLimit = fEffort ? p->pPars->nBTLimitPo : (Vec_BitEntry(p->vFails, iObj0) || Vec_BitEntry(p->vFails, iObj1)) ? Abc_MaxInt(1, p->pPars->nBTLimit/10) : p->pPars->nBTLimit; + Gia_Obj_t * pRepr, * pObj; + int nConfEnd, nConfBeg, status;//, iVar0, iVar1, Lits[2]; + int UnsatConflicts[3] = {0}; + //printf( "%d ", nBTLimit ); + if ( iObj1 < iObj0 ) + iObj1 ^= iObj0, iObj0 ^= iObj1, iObj1 ^= iObj0; + assert( iObj0 < iObj1 ); + pRepr = Gia_ManObj( p->pNew, iObj0 ); + pObj = Gia_ManObj( p->pNew, iObj1 ); + *pfEasy = 0; + // check if SAT solver needs recycling + p->nCallsSince++; +// if ( p->nCallsSince > p->pPars->nCallsRecycle && +// Vec_IntSize(&p->pNew->vSuppVars) > p->pPars->nSatVarMax && p->pPars->nSatVarMax ) +// Cec5_ManSatSolverRecycle( p ); +// // add more logic to the solver +// if ( !iObj0 && Cec5_ObjSatId(p->pNew, Gia_ManConst0(p->pNew)) == -1 ) +// Cec5_ObjSetSatId( p->pNew, Gia_ManConst0(p->pNew), sat_solver_addvar(p->pSat) ); +// clk = Abc_Clock(); +// iVar0 = Cec5_ObjGetCnfVar( p, iObj0 ); +// iVar1 = Cec5_ObjGetCnfVar( p, iObj1 ); +// if( p->pPars->jType > 0 ) +// { +// sat_solver_start_new_round( p->pSat ); +// sat_solver_mark_cone( p->pSat, Cec5_ObjSatId(p->pNew, Gia_ManObj(p->pNew, iObj0)) ); +// sat_solver_mark_cone( p->pSat, Cec5_ObjSatId(p->pNew, Gia_ManObj(p->pNew, iObj1)) ); +// } +// p->timeCnf += Abc_Clock() - clk; + // perform solving +// Lits[0] = Abc_Var2Lit(iVar0, 1); +// Lits[1] = Abc_Var2Lit(iVar1, fPhase); +// sat_solver_set_conflict_budget( p->pSat, nBTLimit ); +// nConfBeg = sat_solver_conflictnum( p->pSat ); +// status = sat_solver_solve( p->pSat, Lits, 2 ); +// nConfEnd = sat_solver_conflictnum( p->pSat ); + nConfBeg = 0; + if( !Gia_ObjIsConst0(pRepr) ) + status = CbsP_ManSolve2(pCbs,Gia_Not(pObj),Gia_NotCond(pRepr, fPhase)); + else + status = CbsP_ManSolve2(pCbs,Gia_NotCond(pObj,fPhase),NULL); + nConfEnd = pCbs->Pars.nBTThis; + assert( nConfEnd >= nConfBeg ); + if ( fVerbose ) + { + if ( status == CBS_SAT ) + { + p->nConflicts[0][0] += nConfEnd == nConfBeg; + p->nConflicts[0][1] += nConfEnd - nConfBeg; + p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + else if ( status == CBS_UNSAT ) + { + if ( iObj0 > 0 ) + { + UnsatConflicts[0] = nConfEnd == nConfBeg; + UnsatConflicts[1] = nConfEnd - nConfBeg; + UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + } + else + { + p->nConflicts[1][0] += nConfEnd == nConfBeg; + p->nConflicts[1][1] += nConfEnd - nConfBeg; + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + } + } + if ( status == CBS_UNSAT && iObj0 > 0 ) + { + //Lits[0] = Abc_Var2Lit(iVar0, 0); + //Lits[1] = Abc_Var2Lit(iVar1, !fPhase); + //sat_solver_set_conflict_budget( p->pSat, nBTLimit ); + //nConfBeg = sat_solver_conflictnum( p->pSat ); + //status = sat_solver_solve( p->pSat, Lits, 2 ); + //nConfEnd = sat_solver_conflictnum( p->pSat ); + nConfBeg = 0; + status = CbsP_ManSolve2(pCbs,pObj,Gia_NotCond(pRepr,!fPhase)); + nConfEnd = pCbs->Pars.nBTThis; + assert( nConfEnd >= nConfBeg ); + if ( fVerbose ) + { + if ( status == CBS_SAT ) + { + p->nConflicts[0][0] += nConfEnd == nConfBeg; + p->nConflicts[0][1] += nConfEnd - nConfBeg; + p->nConflicts[0][2] = Abc_MaxInt(p->nConflicts[0][2], nConfEnd - nConfBeg); + *pfEasy = nConfEnd == nConfBeg; + } + else if ( status == CBS_UNSAT ) + { + UnsatConflicts[0] &= nConfEnd == nConfBeg; + UnsatConflicts[1] += nConfEnd - nConfBeg; + UnsatConflicts[2] = Abc_MaxInt(p->nConflicts[1][2], nConfEnd - nConfBeg); + + p->nConflicts[1][0] += UnsatConflicts[0]; + p->nConflicts[1][1] += UnsatConflicts[1]; + p->nConflicts[1][2] = Abc_MaxInt(p->nConflicts[1][2], UnsatConflicts[2]); + *pfEasy = UnsatConflicts[0]; + } + } + } + //if ( status == GLUCOSE_UNDEC ) + // printf( "* " ); + return status; +} + + +int Cec5_ManSweepNodeCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj, int iRepr, int fTagFail ) +{ + extern int CbsP_ManSolve2( CbsP_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 ); + abctime clk = Abc_Clock(); + int i, status, fEasy, RetValue = 1; + Gia_Obj_t * pObj = Gia_ManObj( p->pAig, iObj ); + Gia_Obj_t * pRepr = Gia_ManObj( p->pAig, iRepr ); + int fCompl = Abc_LitIsCompl(pObj->Value) ^ Abc_LitIsCompl(pRepr->Value) ^ pObj->fPhase ^ pRepr->fPhase; + //int fCompl = pObj->fPhase ^ pRepr->fPhase; + int fEffort = p->vCoDrivers ? Vec_BitEntry(p->vCoDrivers, iObj) || Vec_BitEntry(p->vCoDrivers, iRepr) : 0; + //status = Cec5_ManSolveTwo( p, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort ); + + status = Cec5_ManSolveTwoCbs( p, pCbs, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, &fEasy, p->pPars->fVerbose, fEffort ); + //status = CbsP_ManSolve2(pCbs,pObj,pRepr); + if ( status == CBS_SAT ) + { + int iLit; + Vec_BitWriteEntry( p->vCexSite, iObj, 1 ); +// int iPatsOld = p->pAig->iPatsPi; +// //printf( "Disproved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) ); + p->nSatSat++; + p->nPatterns++; + Vec_IntClear( p->vPat ); + Vec_IntForEachEntry( pCbs->vModel, iLit, i ) + Vec_IntPush( p->vPat, Abc_LitNot(iLit) ); + assert( p->pAig->iPatsPi >= 0 && p->pAig->iPatsPi < 64 * p->pAig->nSimWords - 1 ); + p->pAig->iPatsPi++; + Vec_IntForEachEntry( p->vPat, iLit, i ) + Vec_IntPush( p->vPiPatsCache, iLit ); + Vec_IntPush( p->vPiPatsCache, -1 ); + + if ( fEasy ) + p->timeSatSat0 += Abc_Clock() - clk; + else + p->timeSatSat += Abc_Clock() - clk; + RetValue = 0; + + p->simTravId = p->pAig->iPatsPi / p->LocalBatchSize; + if( (p->pAig->iPatsPi % p->LocalBatchSize) == 0 || 1 == p->LocalBatchSize ) + Cec5_FlushCache2Pattern(p); + +// // this is not needed, but we keep it here anyway, because it takes very little time +// //Cec5_ManVerify( p->pNew, Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value), fCompl, p->pSat ); +// // resimulated once in a while + Cec5_ManCheckGlobalSim(p); + } + else if ( status == CBS_UNSAT ) + { + //printf( "Proved: %d == %d.\n", Abc_Lit2Var(pRepr->Value), Abc_Lit2Var(pObj->Value) ); + p->nSatUnsat++; + pObj->Value = Abc_LitNotCond( pRepr->Value, fCompl ); + assert( !Gia_ObjProved( p->pAig, iObj ) ); + Gia_ObjSetProved( p->pAig, iObj ); + if ( iRepr == 0 ) + p->iLastConst = iObj; + if ( fEasy ) + p->timeSatUnsat0 += Abc_Clock() - clk; + else + p->timeSatUnsat += Abc_Clock() - clk; + RetValue = 1; + } + else + { + if( fTagFail ){ + p->nSatUndec++; + assert( status == CBS_UNDEC ); + Gia_ObjSetFailed( p->pAig, iObj ); + Gia_ObjSetFailed( p->pAig, iRepr ); + Vec_BitWriteEntry( p->vFails, iObj, 1 ); + p->timeSatUndec += Abc_Clock() - clk; + } + //if ( iRepr ) + //Vec_BitWriteEntry( p->vFails, iRepr, 1 ); + RetValue = 2; + } + return RetValue; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/proof/cec/module.make b/src/proof/cec/module.make index 23595f23a..ed3dac110 100644 --- a/src/proof/cec/module.make +++ b/src/proof/cec/module.make @@ -9,6 +9,7 @@ SRC += src/proof/cec/cecCec.c \ src/proof/cec/cecSat.c \ src/proof/cec/cecSatG.c \ src/proof/cec/cecSatG2.c \ + src/proof/cec/cecSatG3.c \ src/proof/cec/cecSeq.c \ src/proof/cec/cecSim.c \ src/proof/cec/cecSolve.c \ diff --git a/src/sat/glucose2/AbcGlucose2.cpp b/src/sat/glucose2/AbcGlucose2.cpp index 9a8b97eb2..c1d77587d 100644 --- a/src/sat/glucose2/AbcGlucose2.cpp +++ b/src/sat/glucose2/AbcGlucose2.cpp @@ -1536,6 +1536,12 @@ int Glucose2_SolveAig(Gia_Man_t * p, Glucose2_Pars * pPars) return (ret == l_True ? 10 : ret == l_False ? 20 : 0); } +extern "C" { + void glucose2_markapprox( void * pSat, int v0, int v1, int nlim ){ + ((Gluco2::Solver*) pSat)->markApprox(v0, v1, nlim); + } +}; + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/glucose2/CGlucoseCore.h b/src/sat/glucose2/CGlucoseCore.h index c0f96fc4e..22de92d2e 100644 --- a/src/sat/glucose2/CGlucoseCore.h +++ b/src/sat/glucose2/CGlucoseCore.h @@ -613,6 +613,85 @@ inline void Solver::prelocate( int base_var_num ){ polarity .prelocate( base_var_num ); } + +inline void Solver::markTill( Var v, int nlim ){ + if( var2TravId[v] == travId ) + return; + + vMarked.push(v); + + if( vMarked.size() >= nlim ) + return; + if( var2TravId[v] == travId-1 || !isTwoFanin(v) ) + goto finalize; + + markTill( getFaninVar0(v), nlim ); + markTill( getFaninVar1(v), nlim ); +finalize: + var2TravId[v] = travId; +} + +inline void Solver::markApprox( Var v0, Var v1, int nlim ){ + int i; + if( travId <= 1 || nSkipMark>=4 || 0 == nlim ) + goto finalize; + + vMarked.shrink_( vMarked.size() ); + travId ++ ; // travId = t+1 + assert(travId>1); + + markTill(v0, nlim); + if( vMarked.size() >= nlim ) + goto finalize; + + markTill(v1, nlim); + if( vMarked.size() >= nlim ) + goto finalize; + + travId -- ; // travId = t + for(i = 0; i < vMarked.size(); i ++){ + var2TravId [ vMarked[i] ] = travId; // set new nodes to time t + var2NodeData[ vMarked[i] ].sort = 0; + } + nSkipMark ++ ; + return; +finalize: + + travId ++ ; + nSkipMark = 0; + markCone(v0); + markCone(v1); +} + +inline void Solver::loadJust_rec( Var v ){ + //assert( value(v) != l_Undef ); + if( var2TravId[v] == travId || value(v) == l_Undef ) + return; + assert( var2TravId[v] == travId-1 ); + var2TravId[v] = travId; + vMarked.push(v); + + if( !isTwoFanin(v) ){ + JustModel.push( mkLit( v, value(v) == l_False ) ); + return; + } + loadJust_rec( getFaninVar0(v) ); + loadJust_rec( getFaninVar1(v) ); +} +inline void Solver::loadJust(){ + int i; + travId ++ ; + JustModel.shrink_(JustModel.size()); + vMarked.shrink_(vMarked.size()); + JustModel.push(toLit(0)); + for(i = 0; i < assumptions.size(); i ++) + loadJust_rec( var(assumptions[i]) ); + JustModel[0] = toLit( JustModel.size()-1 ); + travId -- ; + for(i = 0; i < vMarked.size(); i ++) + var2TravId[ vMarked[i] ] = travId; +} + }; ABC_NAMESPACE_IMPL_END diff --git a/src/sat/glucose2/Glucose2.cpp b/src/sat/glucose2/Glucose2.cpp index 4b4c28e78..d345cd0a1 100644 --- a/src/sat/glucose2/Glucose2.cpp +++ b/src/sat/glucose2/Glucose2.cpp @@ -186,6 +186,7 @@ Solver::Solver() : itpc = ca.alloc(tmp); ca[itpc].shrink( ca[itpc].size() ); + nSkipMark = 0; #endif } @@ -1452,15 +1453,20 @@ printf("c ==================================[ Search Statistics (every %6d confl if (status == l_True){ if( justUsage() ){ - JustModel.shrink_(JustModel.size()); - assert(jheap.empty()); - //JustModel.growTo(nVars()); - int i = 0, j = 0; - JustModel.push(toLit(0)); - for (; i < trail.size(); i++) - if( isRoundWatch(var(trail[i])) && !isTwoFanin(var(trail[i])) ) - JustModel.push(trail[i]), j++; - JustModel[0] = toLit(j); + if( nSkipMark ){ + loadJust(); + } else { + JustModel.shrink_(JustModel.size()); + assert(jheap.empty()); + //JustModel.growTo(nVars()); + int i = 0, j = 0; + JustModel.push(toLit(0)); + for (; i < trail.size(); i++) + if( isRoundWatch(var(trail[i])) && !isTwoFanin(var(trail[i])) ) + JustModel.push(trail[i]), j++; + JustModel[0] = toLit(j); + } + } else { // Extend & copy model: model.shrink_(model.size()); @@ -1743,6 +1749,9 @@ void Solver::reset() itpc = ca.alloc(tmp); ca[itpc].shrink( ca[itpc].size() ); } + + vMarked.shrink_( vMarked.size() ); + nSkipMark = 0; #endif } diff --git a/src/sat/glucose2/Solver.h b/src/sat/glucose2/Solver.h index b1d38d798..004fdc95a 100644 --- a/src/sat/glucose2/Solver.h +++ b/src/sat/glucose2/Solver.h @@ -453,7 +453,15 @@ protected: Heap2 jheap; vec jlevel; vec jnext; + + int nSkipMark; + void loadJust_rec( Var v ); + void loadJust(); + vec vMarked; public: + void markTill( Var v0, int nlim ); + void markApprox( Var v0, Var v1, int nlim ); + void prelocate( int var_num ); void setVarFaninLits( Var v, Lit lit1, Lit lit2 ); void setVarFaninLits( int v, int lit1, int lit2 ){ setVarFaninLits( Var(v), toLit(lit1), toLit(lit2) ); } From cb30ea0516cf85b839794c4755f6071a02e55537 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 09:59:22 -0700 Subject: [PATCH 46/74] Experiments with SAT sweeping. --- src/base/abci/abc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 6f0f7a346..90d85bded 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -36996,9 +36996,10 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Gia_Man_t * Cec2_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec3_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); - extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); + extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle ); Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp; int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0; + int fUseAlgoG3 = 0, fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500; Cec4_ManSetParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxywvh" ) ) != EOF ) @@ -37153,7 +37154,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) else if ( fUseAlgoX ) pTemp = Cec4_ManSimulateTest( pAbc->pGia, pPars ); else if ( fUseAlgoY ) - pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars ); + pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars, fCbs, approxLim, subBatchSz, adaRecycle ); else pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 ); Abc_FrameUpdateGia( pAbc, pTemp ); From 1abd0457abb9f522da48e24996545b155285bac9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 10:25:46 -0700 Subject: [PATCH 47/74] Experiments with SAT sweeping. --- src/base/abci/abc.c | 2 +- src/proof/cec/cecSatG3.c | 3 +-- src/sat/glucose2/AbcGlucose2.cpp | 25 +++++++++++++++++++------ src/sat/glucose2/AbcGlucose2.h | 1 + 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 90d85bded..3312ad071 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -36999,7 +36999,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle ); Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp; int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0; - int fUseAlgoG3 = 0, fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500; + int fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500; Cec4_ManSetParams( pPars ); Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxywvh" ) ) != EOF ) diff --git a/src/proof/cec/cecSatG3.c b/src/proof/cec/cecSatG3.c index bdfa0f901..eaad455bf 100644 --- a/src/proof/cec/cecSatG3.c +++ b/src/proof/cec/cecSatG3.c @@ -1564,9 +1564,8 @@ void Cec5_ManLoadInstance( Cec5_Man_t * p, int iObj0, int iObj1, int * piVar0, i int iVar1 = Cec5_ObjGetCnfVar( p, iObj1 ); if( p->pPars->jType > 0 ) { - extern void glucose2_markapprox( void * pSat, int v0, int v1, int nlim ); int nlim = p->approxLim; - glucose2_markapprox( p->pSat, iVar0, iVar1, nlim ); + bmcg2_sat_solver_markapprox( p->pSat, iVar0, iVar1, nlim ); } * piVar0 = iVar0; diff --git a/src/sat/glucose2/AbcGlucose2.cpp b/src/sat/glucose2/AbcGlucose2.cpp index c1d77587d..99ca112ae 100644 --- a/src/sat/glucose2/AbcGlucose2.cpp +++ b/src/sat/glucose2/AbcGlucose2.cpp @@ -132,6 +132,10 @@ void glucose2_solver_setstop(Gluco2::SimpSolver* S, int * pstop) S->pstop = pstop; } +void glucose2_markapprox( Gluco2::SimpSolver* S, int v0, int v1, int nlim ) +{ + S->markApprox(v0, v1, nlim); +} /**Function************************************************************* @@ -228,6 +232,11 @@ void bmcg2_sat_solver_set_stop(bmcg2_sat_solver* s, int * pstop) glucose2_solver_setstop((Gluco2::SimpSolver*)s, pstop); } +void bmcg2_sat_solver_markapprox(bmcg2_sat_solver* s, int v0, int v1, int nlim) +{ + glucose2_markapprox((Gluco2::SimpSolver*)s, v0, v1, nlim); +} + abctime bmcg2_sat_solver_set_runtime_limit(bmcg2_sat_solver* s, abctime Limit) { abctime nRuntimeLimit = ((Gluco2::SimpSolver*)s)->nRuntimeLimit; @@ -474,6 +483,11 @@ void glucose2_solver_setstop(Gluco2::Solver* S, int * pstop) S->pstop = pstop; } +void glucose2_markapprox( Gluco2::Solver* S, int v0, int v1, int nlim ) +{ + S->markApprox(v0, v1, nlim); +} + /**Function************************************************************* @@ -570,6 +584,11 @@ void bmcg2_sat_solver_set_stop(bmcg2_sat_solver* s, int * pstop) glucose2_solver_setstop((Gluco2::Solver*)s, pstop); } +void bmcg2_sat_solver_markapprox(bmcg2_sat_solver* s, int v0, int v1, int nlim) +{ + glucose2_markapprox((Gluco2::Solver*)s, v0, v1, nlim); +} + abctime bmcg2_sat_solver_set_runtime_limit(bmcg2_sat_solver* s, abctime Limit) { abctime nRuntimeLimit = ((Gluco2::Solver*)s)->nRuntimeLimit; @@ -1536,12 +1555,6 @@ int Glucose2_SolveAig(Gia_Man_t * p, Glucose2_Pars * pPars) return (ret == l_True ? 10 : ret == l_False ? 20 : 0); } -extern "C" { - void glucose2_markapprox( void * pSat, int v0, int v1, int nlim ){ - ((Gluco2::Solver*) pSat)->markApprox(v0, v1, nlim); - } -}; - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/sat/glucose2/AbcGlucose2.h b/src/sat/glucose2/AbcGlucose2.h index 9299d2905..d1c156395 100644 --- a/src/sat/glucose2/AbcGlucose2.h +++ b/src/sat/glucose2/AbcGlucose2.h @@ -86,6 +86,7 @@ extern int bmcg2_sat_solver_elim_varnum(bmcg2_sat_solver* s); extern int * bmcg2_sat_solver_read_cex( bmcg2_sat_solver* s ); extern int bmcg2_sat_solver_read_cex_varvalue( bmcg2_sat_solver* s, int ); extern void bmcg2_sat_solver_set_stop( bmcg2_sat_solver* s, int * pstop ); +extern void bmcg2_sat_solver_markapprox(bmcg2_sat_solver* s, int v0, int v1, int nlim); extern abctime bmcg2_sat_solver_set_runtime_limit( bmcg2_sat_solver* s, abctime Limit ); extern void bmcg2_sat_solver_set_conflict_budget( bmcg2_sat_solver* s, int Limit ); extern int bmcg2_sat_solver_varnum( bmcg2_sat_solver* s ); From ca6dd4ed17916afb92c4da36ae4ffc8e135f2723 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 13:56:19 -0700 Subject: [PATCH 48/74] Bug fix in &uif. --- src/aig/gia/giaDup.c | 16 +++++++++--- src/base/abci/abc.c | 6 +++++ src/base/wln/wlnCom.c | 14 +++++++---- src/base/wln/wlnRead.c | 53 +++++++++++++++++++++++++++++++--------- src/proof/cec/cecSatG3.c | 2 ++ 5 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 1164e16b4..16ca502c5 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -5301,7 +5301,7 @@ Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p ) } iUif = Gia_ManDupUifConstr( pNew, p, pvMap ); Gia_ManForEachCo( p, pObj, i ) - Gia_ManAppendCo( pNew, Gia_ManAppendAnd(pNew, pObj->Value, iUif) ); + Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, pObj->Value, iUif) ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); Vec_WecFree( pvMap[0] ); @@ -5336,23 +5336,31 @@ Gia_Man_t * Gia_ManDupBlackBox( Gia_Man_t * p ) Vec_Int_t * vMap = Gia_ManDupBlackBoxBuildMap( p ); Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; - int i, k = 0; + int i, k = 0, iCi = 0, nCis = Gia_ManCiNum(p) + Vec_IntSum(vMap); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; + for ( i = 0; i < nCis; i++ ) + Gia_ManAppendCi( pNew ); Gia_ManHashAlloc( pNew ); Gia_ManForEachObj1( p, pObj, i ) { if ( Gia_ObjIsBuf(pObj) ) - pObj->Value = Vec_IntEntry(vMap, k++) ? Gia_ManAppendCi(pNew) : Gia_ObjFanin0Copy(pObj); // out/in + { + if ( Vec_IntEntry(vMap, k++) ) // out + pObj->Value = Gia_ManCiLit(pNew, iCi++); + else + pObj->Value = Gia_ObjFanin0Copy(pObj); + } else if ( Gia_ObjIsAnd(pObj) ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); else if ( Gia_ObjIsCi(pObj) ) - pObj->Value = Gia_ManAppendCi( pNew ); + pObj->Value = Gia_ManCiLit(pNew, iCi++); else if ( Gia_ObjIsCo(pObj) ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); } + assert( k == p->nBufs && iCi == nCis ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); Vec_IntFree( vMap ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 3312ad071..46b2215a8 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -37157,6 +37157,12 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars, fCbs, approxLim, subBatchSz, adaRecycle ); else pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 ); + if ( pAbc->pGia->pCexSeq != NULL ) + { + pAbc->Status = 0; + pAbc->nFrames = 0; + Abc_FrameReplaceCex( pAbc, &pAbc->pGia->pCexSeq ); + } Abc_FrameUpdateGia( pAbc, pTemp ); return 0; diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index dcf12229e..6b754457c 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -221,15 +221,18 @@ usage: ******************************************************************************/ int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fVerbose ); + extern void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fInv, int fVerbose ); Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); char ** pArgvNew; int nArgcNew; - int c, fVerbose = 0; + int c, fInv = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ivh" ) ) != EOF ) { switch ( c ) { + case 'i': + fInv ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -251,11 +254,12 @@ int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandGraft(): This command expects one AIG file name on the command line.\n" ); return 1; } - Wln_LibGraftOne( pLib, pArgvNew[0], pArgvNew[1], fVerbose ); + Wln_LibGraftOne( pLib, pArgvNew[0], pArgvNew[1], fInv, fVerbose ); return 0; usage: - Abc_Print( -2, "usage: %%graft [-vh] \n" ); + Abc_Print( -2, "usage: %%graft [-ivh] \n" ); Abc_Print( -2, "\t replace instances of module1 by those of module2\n" ); + Abc_Print( -2, "\t-i : toggle using inverse grafting [default = %s]\n", fInv? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 8cd4af0cd..ed59358f5 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -48,6 +48,7 @@ struct Rtl_Lib_t_ Vec_Int_t * vTokens; // temp tokens int pMap[MAX_MAP]; // temp map Vec_Int_t * vMap; // mapping NameId into wires + Vec_Int_t * vInverses; // inverse equivalences Vec_Int_t vAttrTemp; // temp Vec_Int_t vTemp[TEMP_NUM]; // temp }; @@ -325,6 +326,7 @@ void Rtl_LibFree( Rtl_Lib_t * p ) for ( i = 0; i < TEMP_NUM; i++ ) ABC_FREE( p->vTemp[i].pArray ); Vec_IntFreeP( &p->vMap ); + Vec_IntFreeP( &p->vInverses ); Vec_IntFreeP( &p->vTokens ); Abc_NamStop( p->pManName ); Vec_PtrFree( p->vNtks ); @@ -1764,20 +1766,38 @@ void Rtl_NtkBlastConnect( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCon ) } void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) { + extern void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs ); extern Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ); extern void Gia_ManDupRebuild( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vLits, int fBufs ); extern int Gia_ManFindFirst( Rtl_Ntk_t * p, int * pnOuts ); Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); int nIns = 0, nOuts = 0, nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 ); - int k, Par, Val, nBits = 0; - //printf( "Blasting %s -> %s...\n", Rtl_NtkName(p), Rtl_NtkName(pModel) ); + int k, Par, Val, iThis = -1, nBits = 0; + int fFound = 0; + //int fFound = p->pLib->vInverses && (iThis = Vec_IntFind(p->pLib->vInverses, pModel->NameId)) >= 0; Vec_IntClear( &p->vBitTemp ); Rtl_CellForEachInput( p, pCell, Par, Val, k ) Rtl_NtkCollectSignalRange( p, Val ); // if ( pModel->pGia == NULL ) // pModel->pGia = Rtl_NtkBlast( pModel ); assert( pModel->pGia ); - if ( pModel->fRoot ) + if ( fFound ) + { + // check if the previous one is the inverse one + int iThat = Vec_IntEntry( p->pLib->vInverses, iThis ^ 1 ); + //printf( "Blasting %s -> %s...\n", Rtl_NtkName(p), Rtl_NtkName(pModel) ); + //Rtl_NtkPrintBufs( p, pNew->vBarBufs ); + if ( Vec_IntEntry(pNew->vBarBufs, Vec_IntSize(pNew->vBarBufs)-1) == Abc_Var2Lit(iThat, 1) && + Vec_IntEntry(pNew->vBarBufs, Vec_IntSize(pNew->vBarBufs)-2) == Abc_Var2Lit(iThat, 0) ) + { + //printf( "Found matching boundary.\n" ); + } + nIns = nOuts1; + Vec_IntForEachEntry( &p->vBitTemp, Val, k ) + Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); + Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) ); + } + else if ( pModel->fRoot ) { nIns = Vec_IntSize(&p->vBitTemp); Vec_IntForEachEntry( &p->vBitTemp, Val, k ) @@ -1788,7 +1808,7 @@ void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, !pModel->fRoot ); if ( !pModel->fRoot ) Vec_IntAppend( pNew->vBarBufs, pModel->pGia->vBarBufs ); - if ( pModel->fRoot ) + if ( pModel->fRoot || fFound ) { nOuts = Vec_IntSize(&p->vBitTemp); Vec_IntForEachEntry( &p->vBitTemp, Val, k ) @@ -2616,7 +2636,7 @@ Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ) SeeAlso [] ***********************************************************************/ -void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fVerbose ) +void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fInv, int fVerbose ) { int Name1 = Wln_ReadFindToken( pModule1, p->pManName ); int Name2 = Wln_ReadFindToken( pModule2, p->pManName ); @@ -2633,12 +2653,23 @@ void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fVerb Rtl_Ntk_t * pNtk1 = Rtl_LibNtk(p, iNtk1); Rtl_Ntk_t * pNtk2 = Rtl_LibNtk(p, iNtk2); assert( iNtk1 != iNtk2 ); - printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n", - Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); - pNtk1->iCopy = iNtk2; - // Rtl_LibSetReplace( p, vGuide ); - Rtl_LibUpdateBoxes( p ); - Rtl_LibReorderModules( p ); + if ( fInv ) + { + printf( "Setting \"%s\" (appearing %d times) and \"%s\" (appearing %d times) as inverse-equivalent.\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + if ( p->vInverses == NULL ) + p->vInverses = Vec_IntAlloc( 10 ); + Vec_IntPushTwo( p->vInverses, pNtk1->NameId, pNtk2->NameId ); + } + else + { + printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + pNtk1->iCopy = iNtk2; + // Rtl_LibSetReplace( p, vGuide ); + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + } } } diff --git a/src/proof/cec/cecSatG3.c b/src/proof/cec/cecSatG3.c index eaad455bf..5f22937c2 100644 --- a/src/proof/cec/cecSatG3.c +++ b/src/proof/cec/cecSatG3.c @@ -2125,6 +2125,8 @@ Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, { Gia_Man_t * pNew = NULL; Cec5_ManPerformSweeping( p, pPars, &pNew, 0, fCbs, approxLim, subBatchSz, adaRecycle ); + if ( pNew == NULL ) + pNew = Gia_ManDup( p ); return pNew; } From dd81af8170f46dfbe801fa75c127664201e19552 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 14:37:46 -0700 Subject: [PATCH 49/74] Supporting multiple box types in &uif. --- src/aig/gia/giaDup.c | 53 ++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 16ca502c5..9a82aa3c1 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -5232,26 +5232,39 @@ Gia_Man_t * Gia_ManDupAddPis( Gia_Man_t * p, int nMulti ) SeeAlso [] ***********************************************************************/ +Vec_Int_t * Gia_ManDupUifBoxTypes( Vec_Int_t * vBarBufs ) +{ + Vec_Int_t * vTypes = Vec_IntAlloc( 10 ); + int i, Entry; + Vec_IntForEachEntry( vBarBufs, Entry, i ) + if ( Vec_IntFind(vTypes, Entry & 0xFFFE) < 0 ) + Vec_IntPush( vTypes, Entry & 0xFFFE ); + return vTypes; +} Vec_Wec_t ** Gia_ManDupUifBuildMap( Gia_Man_t * p ) { - Vec_Wec_t ** pvMap = ABC_ALLOC( Vec_Wec_t *, 2 ); + Vec_Int_t * vTypes = Gia_ManDupUifBoxTypes( p->vBarBufs ); + Vec_Wec_t ** pvMap = ABC_ALLOC( Vec_Wec_t *, 2*Vec_IntSize(vTypes) ); Vec_Int_t * vBufs = Vec_IntAlloc( p->nBufs ); Gia_Obj_t * pObj; int i, Item, j, k = 0; - pvMap[0] = Vec_WecAlloc(10); - pvMap[1] = Vec_WecAlloc(10); Gia_ManForEachObj1( p, pObj, i ) if ( Gia_ObjIsBuf(pObj) ) Vec_IntPush( vBufs, i ); assert( p->nBufs == Vec_IntSize(vBufs) ); + for ( i = 0; i < 2*Vec_IntSize(vTypes); i++ ) + pvMap[i] = Vec_WecAlloc( 10 ); Vec_IntForEachEntry( p->vBarBufs, Item, i ) { - Vec_Int_t * vVec = Vec_WecPushLevel(pvMap[Item&1]); + int Type = Vec_IntFind( vTypes, Item & 0xFFFE ); + Vec_Int_t * vVec = Vec_WecPushLevel(pvMap[2*Type + (Item&1)]); for ( j = 0; j < (Item >> 16); j++ ) Vec_IntPush( vVec, Vec_IntEntry(vBufs, k++) ); } + Vec_IntFree( vTypes ); Vec_IntFree( vBufs ); assert( p->nBufs == k ); - assert( Vec_WecSize(pvMap[0]) == Vec_WecSize(pvMap[1]) ); + for ( i = 0; i < Vec_IntSize(vTypes); i++ ) + assert( Vec_WecSize(pvMap[2*i+0]) == Vec_WecSize(pvMap[2*i+1]) ); return pvMap; } int Gia_ManDupUifConstrOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vVec0, Vec_Int_t * vVec1 ) @@ -5264,22 +5277,26 @@ int Gia_ManDupUifConstrOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vVec0, Vec_IntFree( vTemp ); return iRes; } -int Gia_ManDupUifConstr( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t ** pvMap ) +int Gia_ManDupUifConstr( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Wec_t ** pvMap, int nTypes ) { - int i, k, iUif = 1; - assert( Vec_WecSize(pvMap[0]) == Vec_WecSize(pvMap[1]) ); - for ( i = 0; i < Vec_WecSize(pvMap[0]); i++ ) - for ( k = i + 1; k < Vec_WecSize(pvMap[0]); k++ ) + int t, i, k, iUif = 1; + for ( t = 0; t < nTypes; t++ ) { - int iCond1 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[0], i), Vec_WecEntry(pvMap[0], k) ); - int iCond2 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[1], i), Vec_WecEntry(pvMap[1], k) ); - int iRes = Gia_ManHashOr( pNew, Abc_LitNot(iCond1), iCond2 ); - iUif = Gia_ManHashAnd( pNew, iUif, iRes ); + assert( Vec_WecSize(pvMap[2*t+0]) == Vec_WecSize(pvMap[2*t+1]) ); + for ( i = 0; i < Vec_WecSize(pvMap[2*t+0]); i++ ) + for ( k = i + 1; k < Vec_WecSize(pvMap[2*t+0]); k++ ) + { + int iCond1 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[2*t+0], i), Vec_WecEntry(pvMap[2*t+0], k) ); + int iCond2 = Gia_ManDupUifConstrOne( pNew, p, Vec_WecEntry(pvMap[2*t+1], i), Vec_WecEntry(pvMap[2*t+1], k) ); + int iRes = Gia_ManHashOr( pNew, Abc_LitNot(iCond1), iCond2 ); + iUif = Gia_ManHashAnd( pNew, iUif, iRes ); + } } return iUif; } Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p ) { + Vec_Int_t * vTypes = Gia_ManDupUifBoxTypes( p->vBarBufs ); Vec_Wec_t ** pvMap = Gia_ManDupUifBuildMap( p ); Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, iUif = 0; @@ -5299,16 +5316,18 @@ Gia_Man_t * Gia_ManDupUif( Gia_Man_t * p ) else if ( Gia_ObjIsCo(pObj) ) pObj->Value = Gia_ObjFanin0Copy(pObj); } - iUif = Gia_ManDupUifConstr( pNew, p, pvMap ); + iUif = Gia_ManDupUifConstr( pNew, p, pvMap, Vec_IntSize(vTypes) ); Gia_ManForEachCo( p, pObj, i ) Gia_ManAppendCo( pNew, Gia_ManHashAnd(pNew, pObj->Value, iUif) ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); - Vec_WecFree( pvMap[0] ); - Vec_WecFree( pvMap[1] ); + for ( i = 0; i < 2*Vec_IntSize(vTypes); i++ ) + Vec_WecFree( pvMap[i] ); ABC_FREE( pvMap ); if ( p->vBarBufs ) pNew->vBarBufs = Vec_IntDup( p->vBarBufs ); + printf( "Added UIF constraints for %d type%s of boxes.\n", Vec_IntSize(vTypes), Vec_IntSize(vTypes) > 1 ? "s" :"" ); + Vec_IntFree( vTypes ); return pNew; } From 7693ce6a6ce542d7ef317ea4319f4622693ab016 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 19:15:22 -0700 Subject: [PATCH 50/74] Bug fix in &uif. --- src/aig/gia/giaDup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 9a82aa3c1..cc5015625 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -5260,11 +5260,11 @@ Vec_Wec_t ** Gia_ManDupUifBuildMap( Gia_Man_t * p ) for ( j = 0; j < (Item >> 16); j++ ) Vec_IntPush( vVec, Vec_IntEntry(vBufs, k++) ); } - Vec_IntFree( vTypes ); - Vec_IntFree( vBufs ); assert( p->nBufs == k ); for ( i = 0; i < Vec_IntSize(vTypes); i++ ) assert( Vec_WecSize(pvMap[2*i+0]) == Vec_WecSize(pvMap[2*i+1]) ); + Vec_IntFree( vTypes ); + Vec_IntFree( vBufs ); return pvMap; } int Gia_ManDupUifConstrOne( Gia_Man_t * pNew, Gia_Man_t * p, Vec_Int_t * vVec0, Vec_Int_t * vVec1 ) From 9e164ec52d58655354df6176a51e455270df427f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 20:15:15 -0700 Subject: [PATCH 51/74] Adding a switch to complement outputs after collapsing. --- src/base/wln/wlnCom.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index 6b754457c..31e0bea3f 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -335,9 +335,9 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_Man_t * pNew = NULL; Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); char * pTopModule = NULL; - int c, fVerbose = 0; + int c, fInv = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Tvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Tivh" ) ) != EOF ) { switch ( c ) { @@ -350,6 +350,9 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) pTopModule = argv[globalUtilOptind]; globalUtilOptind++; break; + case 'i': + fInv ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -365,12 +368,15 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } pNew = Rtl_LibCollapse( pLib, pTopModule, fVerbose ); + if ( fInv ) + Gia_ManInvertPos( pNew ); Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: %%collapse [-T ] [-vh] \n" ); + Abc_Print( -2, "usage: %%collapse [-T ] [-ivh] \n" ); Abc_Print( -2, "\t collapse hierarchical design into an AIG\n" ); Abc_Print( -2, "\t-T : specify the top module of the design [default = none]\n" ); + Abc_Print( -2, "\t-i : toggle complementing miter outputs after collapsing [default = %s]\n", fInv? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; From c68fcae4457bddd80cd3d077a39b6e3381bbd37b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 20:57:41 -0700 Subject: [PATCH 52/74] A trivial changeset. --- src/base/wln/wlnCom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index 31e0bea3f..f3adaf082 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -79,7 +79,6 @@ void Wln_End( Abc_Frame_t * pAbc ) Wln_AbcUpdateRtl( pAbc, NULL ); } - /**Function******************************************************************** Synopsis [] From 0fc56e71997b09fef9cc35f2e3423df723e1e9ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Apr 2022 10:39:54 -0700 Subject: [PATCH 53/74] Experiments with word-level data structures. --- src/base/wln/wlnCom.c | 8 +- src/base/wln/wlnRead.c | 277 ++++++++++++++++++++++++++++++++--------- 2 files changed, 220 insertions(+), 65 deletions(-) diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index f3adaf082..0314fff32 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -220,7 +220,7 @@ usage: ******************************************************************************/ int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fInv, int fVerbose ); + extern void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, int fVerbose ); Rtl_Lib_t * pLib = Wln_AbcGetRtl(pAbc); char ** pArgvNew; int nArgcNew; int c, fInv = 0, fVerbose = 0; @@ -248,12 +248,12 @@ int Abc_CommandGraft( Abc_Frame_t * pAbc, int argc, char ** argv ) } pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; - if ( nArgcNew != 2 ) + if ( nArgcNew != 0 && nArgcNew != 2 ) { Abc_Print( -1, "Abc_CommandGraft(): This command expects one AIG file name on the command line.\n" ); return 1; } - Wln_LibGraftOne( pLib, pArgvNew[0], pArgvNew[1], fInv, fVerbose ); + Wln_LibGraftOne( pLib, pArgvNew, nArgcNew, fInv, fVerbose ); return 0; usage: Abc_Print( -2, "usage: %%graft [-ivh] \n" ); @@ -302,7 +302,7 @@ int Abc_CommandHierarchy( Abc_Frame_t * pAbc, int argc, char ** argv ) } pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; - if ( nArgcNew < 1 ) + if ( nArgcNew < 0 ) { Abc_Print( -1, "Abc_CommandHierarchy(): This command expects one AIG file name on the command line.\n" ); return 1; diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index ed59358f5..cd868185e 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -48,6 +48,7 @@ struct Rtl_Lib_t_ Vec_Int_t * vTokens; // temp tokens int pMap[MAX_MAP]; // temp map Vec_Int_t * vMap; // mapping NameId into wires + Vec_Int_t * vDirects; // direct equivalences Vec_Int_t * vInverses; // inverse equivalences Vec_Int_t vAttrTemp; // temp Vec_Int_t vTemp[TEMP_NUM]; // temp @@ -326,6 +327,7 @@ void Rtl_LibFree( Rtl_Lib_t * p ) for ( i = 0; i < TEMP_NUM; i++ ) ABC_FREE( p->vTemp[i].pArray ); Vec_IntFreeP( &p->vMap ); + Vec_IntFreeP( &p->vDirects ); Vec_IntFreeP( &p->vInverses ); Vec_IntFreeP( &p->vTokens ); Abc_NamStop( p->pManName ); @@ -361,17 +363,24 @@ int Rtl_LibFindTwoModules( Rtl_Lib_t * p, int Name1, int Name2 ) int iNtk1 = Rtl_LibFindModule( p, Name1 ); if ( Name2 == -1 ) return (iNtk1 << 16) | iNtk1; + else if ( iNtk1 == -1 ) + return -1; else { int Counts1[4] = {0}, Counts2[4] = {0}; int iNtk2 = Rtl_LibFindModule( p, Name2 ); - Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); - Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); - Rtl_NtkCountPio( pNtk1, Counts1 ); - Rtl_NtkCountPio( pNtk2, Counts2 ); - if ( Counts1[1] != Counts2[1] || Counts1[3] != Counts2[3] ) - iNtk1 = Rtl_LibFindModule2( p, Name1, iNtk2 ); - return (iNtk1 << 16) | iNtk2; + if ( iNtk2 == -1 ) + return -1; + else + { + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); + Rtl_NtkCountPio( pNtk1, Counts1 ); + Rtl_NtkCountPio( pNtk2, Counts2 ); + if ( Counts1[1] != Counts2[1] || Counts1[3] != Counts2[3] ) + iNtk1 = Rtl_LibFindModule2( p, Name1, iNtk2 ); + return (iNtk1 << 16) | iNtk2; + } } } void Rtl_LibPrintStats( Rtl_Lib_t * p ) @@ -1773,25 +1782,15 @@ void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) Rtl_Ntk_t * pModel = Rtl_NtkModule( p, Rtl_CellModule(pCell)-ABC_INFINITY ); int nIns = 0, nOuts = 0, nOuts1, iFirst1 = Gia_ManFindFirst( pModel, &nOuts1 ); int k, Par, Val, iThis = -1, nBits = 0; - int fFound = 0; - //int fFound = p->pLib->vInverses && (iThis = Vec_IntFind(p->pLib->vInverses, pModel->NameId)) >= 0; + //int fFound = 0; + int fFound = p->pLib->vInverses && (iThis = Vec_IntFind(p->pLib->vInverses, pModel->NameId)) >= 0; + //int iThat = fFound ? Vec_IntEntry( p->pLib->vInverses, iThis ^ 1 ) : -1; Vec_IntClear( &p->vBitTemp ); Rtl_CellForEachInput( p, pCell, Par, Val, k ) Rtl_NtkCollectSignalRange( p, Val ); -// if ( pModel->pGia == NULL ) -// pModel->pGia = Rtl_NtkBlast( pModel ); assert( pModel->pGia ); if ( fFound ) { - // check if the previous one is the inverse one - int iThat = Vec_IntEntry( p->pLib->vInverses, iThis ^ 1 ); - //printf( "Blasting %s -> %s...\n", Rtl_NtkName(p), Rtl_NtkName(pModel) ); - //Rtl_NtkPrintBufs( p, pNew->vBarBufs ); - if ( Vec_IntEntry(pNew->vBarBufs, Vec_IntSize(pNew->vBarBufs)-1) == Abc_Var2Lit(iThat, 1) && - Vec_IntEntry(pNew->vBarBufs, Vec_IntSize(pNew->vBarBufs)-2) == Abc_Var2Lit(iThat, 0) ) - { - //printf( "Found matching boundary.\n" ); - } nIns = nOuts1; Vec_IntForEachEntry( &p->vBitTemp, Val, k ) Vec_IntWriteEntry( &p->vBitTemp, k, (k >= iFirst1 && k < iFirst1 + nOuts1) ? Gia_ManAppendBuf(pNew, Val) : Val ); @@ -1805,9 +1804,13 @@ void Rtl_NtkBlastHierarchy( Gia_Man_t * pNew, Rtl_Ntk_t * p, int * pCell ) Vec_IntWriteEntry( &p->vBitTemp, k, Gia_ManAppendBuf(pNew, Val) ); Vec_IntPush( pNew->vBarBufs, (nIns << 16) | Abc_Var2Lit(pModel->NameId, 0) ); } - Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, !pModel->fRoot ); - if ( !pModel->fRoot ) + if ( fFound || pModel->fRoot ) + Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, 0 ); + else + { + Gia_ManDupRebuild( pNew, pModel->pGia, &p->vBitTemp, 1 ); Vec_IntAppend( pNew->vBarBufs, pModel->pGia->vBarBufs ); + } if ( pModel->fRoot || fFound ) { nOuts = Vec_IntSize(&p->vBitTemp); @@ -1877,21 +1880,25 @@ char * Rtl_ShortenName( char * pName, int nSize ) Buffer[nSize-0] = 0; return Buffer; } +void Rtl_NtkPrintBufOne( Rtl_Lib_t * p, int Lit ) +{ + printf( "%s (%c%d) ", Rtl_LibStr(p, Abc_Lit2Var(Lit&0xFFFF)), Abc_LitIsCompl(Lit)? 'o' : 'i', Lit >> 16 ); +} void Rtl_NtkPrintBufs( Rtl_Ntk_t * p, Vec_Int_t * vBufs ) { int i, Lit; if ( Vec_IntSize(vBufs) ) - printf( "Found %d buffers: ", p->pGia->nBufs ); + printf( "Found %d buffers (%d groups): ", p->pGia->nBufs, Vec_IntSize(vBufs) ); Vec_IntForEachEntry( vBufs, Lit, i ) - printf( "%s (%c%d) ", Rtl_LibStr(p->pLib, Abc_Lit2Var(Lit&0xFFFF)), Abc_LitIsCompl(Lit)? 'o' : 'i', Lit >> 16 ); + Rtl_NtkPrintBufOne( p->pLib, Lit ); if ( Vec_IntSize(vBufs) ) printf( "\n" ); } Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) { + int fDump = 0; Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); int i, iObj, * pCell, nBits = Rtl_NtkRangeWires( p ); - char Buffer[100]; static int counter = 0; Vec_IntFill( &p->vLits, nBits, -1 ); Rtl_NtkMapWires( p, 0 ); Rtl_NtkBlastInputs( pNew, p ); @@ -1919,11 +1926,16 @@ Gia_Man_t * Rtl_NtkBlast( Rtl_Ntk_t * p ) Rtl_NtkMapWires( p, 1 ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); - -sprintf( Buffer, "old%02d.aig", counter++ ); -Gia_AigerWrite( pNew, Buffer, 0, 0, 0 ); -printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) ); -Gia_ManPrintStats( pNew, NULL ); + if ( fDump ) + { + char Buffer[100]; static int counter = 0; + sprintf( Buffer, "old%02d.aig", counter++ ); + Gia_AigerWrite( pNew, Buffer, 0, 0, 0 ); + printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) ); + } + else + printf( "Derived AIG for module %-20s : ", Rtl_ShortenName(Rtl_NtkName(p), 20) ); + Gia_ManPrintStats( pNew, NULL ); return pNew; } void Rtl_LibBlast( Rtl_Lib_t * pLib ) @@ -2125,9 +2137,9 @@ void Rtl_NtkBlast2_rec( Rtl_Ntk_t * p, int iBit, int * pDriver ) } Gia_Man_t * Rtl_NtkBlast2( Rtl_Ntk_t * p ) { + int fDump = 0; Gia_Man_t * pTemp; int i, b, nBits = Rtl_NtkRangeWires( p ); - char Buffer[100]; static int counter = 0; Vec_IntFill( &p->vLits, nBits, -1 ); printf( "Blasting %s...\r", Rtl_NtkName(p) ); Rtl_NtkMapWires( p, 0 ); @@ -2152,11 +2164,16 @@ printf( "Blasting %s...\r", Rtl_NtkName(p) ); Gia_ManStop( pTemp ); // if ( p->fRoot ) // Rtl_NtkPrintBufs( p, p->pGia->vBarBufs ); - -sprintf( Buffer, "new%02d.aig", counter++ ); -Gia_AigerWrite( p->pGia, Buffer, 0, 0, 0 ); -printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) ); -Gia_ManPrintStats( p->pGia, NULL ); + if ( fDump ) + { + char Buffer[100]; static int counter = 0; + sprintf( Buffer, "old%02d.aig", counter++ ); + Gia_AigerWrite( p->pGia, Buffer, 0, 0, 0 ); + printf( "Dumped \"%s\" with AIG for module %-20s : ", Buffer, Rtl_ShortenName(Rtl_NtkName(p), 20) ); + } + else + printf( "Derived AIG for module %-20s : ", Rtl_ShortenName(Rtl_NtkName(p), 20) ); + Gia_ManPrintStats( p->pGia, NULL ); return p->pGia; } void Rtl_LibMark_rec( Rtl_Ntk_t * pNtk ) @@ -2574,6 +2591,108 @@ void Wln_SolveWithGuidance( char * pFileName, Rtl_Lib_t * p ) Vec_IntFree( vRoots ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +static inline void Gia_ManPatchBufDriver( Gia_Man_t * p, int iObj, int iLit0 ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + assert( iObj > Abc_Lit2Var(iLit0) ); + pObj->iDiff0 = pObj->iDiff1 = iObj - Abc_Lit2Var(iLit0); + pObj->fCompl0 = pObj->fCompl1 = Abc_LitIsCompl(iLit0); +} + +Gia_Man_t * Rtl_ReduceInverse( Rtl_Lib_t * pLib, Gia_Man_t * p ) +{ + int fVerbose = 1; + Gia_Man_t * pNew = NULL; + Vec_Wec_t * vBufs = Vec_WecStart( Vec_IntSize(p->vBarBufs) ); + Vec_Int_t * vPairs = Vec_IntAlloc( 10 ); + Vec_Int_t * vTypes = Vec_IntAlloc( p->nBufs ); + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; int i, k = 0, Entry, Buf0, Buf1, fChange = 1; + Vec_IntForEachEntry( p->vBarBufs, Entry, i ) + Vec_IntFillExtra( vTypes, Vec_IntSize(vTypes) + (Entry >> 16), i ); + assert( Vec_IntSize(vTypes) == p->nBufs ); + Gia_ManForEachAnd( p, pObj, i ) + if ( Gia_ObjIsBuf(pObj) ) + { + Vec_WecPush( vBufs, Vec_IntEntry(vTypes, k), i ); + Vec_IntWriteEntry( vMap, i, Vec_IntEntry(vTypes, k++) ); + } + assert( k == p->nBufs ); + Gia_ManForEachAnd( p, pObj, i ) + if ( Gia_ObjIsBuf(pObj) && Gia_ObjIsBuf(Gia_ObjFanin0(pObj)) ) + Vec_IntPushUnique( vPairs, (Vec_IntEntry(vMap, Gia_ObjFaninId0(pObj, i)) << 16) | (Vec_IntEntry(vMap, i) & 0xFFFF) ); + if ( fVerbose ) + { + printf( "Connected boundaries:\n" ); + Vec_IntForEachEntry( vPairs, Entry, i ) + { + printf( "%2d -> %2d : ", Entry >> 16, Entry & 0xFFFF ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry >> 16) ); + printf( " -> " ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry & 0xFFFF) ); + printf( "\n" ); + } + } + while ( fChange ) + { + int Entry1, Entry2, j; + fChange = 0; + Vec_IntForEachEntryDouble( vPairs, Entry1, Entry2, j ) + if ( (Entry1 & 0xFFFF) + 1 == (Entry2 >> 16) ) + { + Vec_IntWriteEntry( vPairs, j, ((Entry1 >> 16) << 16) | (Entry2 & 0xFFFF) ); + Vec_IntDrop( vPairs, j+1 ); + fChange = 1; + break; + } + } +// printf( "Before:\n" ); +// Vec_IntForEachEntry( vPairs, Entry, i ) +// printf( "%d %d\n", Entry >> 16, Entry & 0xFFFF ); + Vec_IntForEachEntry( vPairs, Entry, i ) + Vec_IntWriteEntry( vPairs, i, (((Entry >> 16) - 1) << 16) | ((Entry & 0xFFFF) + 1) ); +// printf( "After:\n" ); +// Vec_IntForEachEntry( vPairs, Entry, i ) +// printf( "%d %d\n", Entry >> 16, Entry & 0xFFFF ); + if ( fVerbose ) + { + printf( "Transformed boundaries:\n" ); + Vec_IntForEachEntry( vPairs, Entry, i ) + { + printf( "%2d -> %2d : ", Entry >> 16, Entry & 0xFFFF ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry >> 16) ); + printf( " -> " ); + Rtl_NtkPrintBufOne( pLib, Vec_IntEntry(p->vBarBufs, Entry & 0xFFFF) ); + printf( "\n" ); + } + } + Vec_IntForEachEntry( vPairs, Entry, i ) + { + Vec_Int_t * vLevel0 = Vec_WecEntry( vBufs, Entry >> 16 ); + Vec_Int_t * vLevel1 = Vec_WecEntry( vBufs, Entry & 0xFFFF ); + Vec_IntForEachEntryTwo( vLevel0, vLevel1, Buf0, Buf1, k ) + Gia_ManPatchBufDriver( p, Buf1, Gia_ObjFaninLit0(Gia_ManObj(p, Buf0), Buf0) ); + } + pNew = Gia_ManRehash( p, 0 ); + Vec_IntFree( vPairs ); + Vec_IntFree( vTypes ); + Vec_IntFree( vMap ); + Vec_WecFree( vBufs ); + return pNew; +} + /**Function************************************************************* Synopsis [] @@ -2616,11 +2735,17 @@ Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ) pGia = Gia_ManDup( pTop->pGia ); if ( pTop->pGia->vBarBufs ) pGia->vBarBufs = Vec_IntDup( pTop->pGia->vBarBufs ); - printf( "Finished computing global AIG for the top module \"%s\". ", Rtl_NtkStr(pTop, NameId) ); + printf( "Derived global AIG for the top module \"%s\". ", Rtl_NtkStr(pTop, NameId) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Rtl_NtkPrintBufs( pTop, pGia->vBarBufs ); Rtl_LibBlastClean( p ); Vec_IntFree( vRoots ); + if ( p->vInverses ) + { + Gia_Man_t * pTemp; + pGia = Rtl_ReduceInverse( p, pTemp = pGia ); + Gia_ManStop( pTemp ); + } } return pGia; } @@ -2636,39 +2761,69 @@ Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ) SeeAlso [] ***********************************************************************/ -void Wln_LibGraftOne( Rtl_Lib_t * p, char * pModule1, char * pModule2, int fInv, int fVerbose ) +void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, int fVerbose ) { - int Name1 = Wln_ReadFindToken( pModule1, p->pManName ); - int Name2 = Wln_ReadFindToken( pModule2, p->pManName ); - int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); - if ( iNtk == -1 ) + if ( nModules == 0 ) { - printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); - return; + Rtl_Ntk_t * pNtk; int i; + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->iCopy = -1; + Vec_IntFreeP( &p->vInverses ); + if ( p->vDirects ) + { + int iName1, iName2; + Vec_IntForEachEntryDouble( p->vDirects, iName1, iName2, i ) + { + int iNtk1 = Rtl_LibFindModule(p, iName1); + int iNtk2 = Rtl_LibFindModule(p, iName2); + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); + pNtk2->iCopy = iNtk1; + } + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + Vec_PtrForEachEntry( Rtl_Ntk_t *, p->vNtks, pNtk, i ) + pNtk->iCopy = -1; + Vec_IntFreeP( &p->vDirects ); + } } else { - int iNtk1 = iNtk >> 16; - int iNtk2 = iNtk & 0xFFFF; - Rtl_Ntk_t * pNtk1 = Rtl_LibNtk(p, iNtk1); - Rtl_Ntk_t * pNtk2 = Rtl_LibNtk(p, iNtk2); - assert( iNtk1 != iNtk2 ); - if ( fInv ) + int Name1 = Wln_ReadFindToken( pModules[0], p->pManName ); + int Name2 = Wln_ReadFindToken( pModules[1], p->pManName ); + int iNtk = Rtl_LibFindTwoModules( p, Name1, Name2 ); + if ( iNtk == -1 ) { - printf( "Setting \"%s\" (appearing %d times) and \"%s\" (appearing %d times) as inverse-equivalent.\n", - Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); - if ( p->vInverses == NULL ) - p->vInverses = Vec_IntAlloc( 10 ); - Vec_IntPushTwo( p->vInverses, pNtk1->NameId, pNtk2->NameId ); + printf( "Cannot find networks \"%s\" and \"%s\" in the design.\n", Rtl_LibStr(p, Name1), Rtl_LibStr(p, Name2) ); + return; } else { - printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n", - Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); - pNtk1->iCopy = iNtk2; - // Rtl_LibSetReplace( p, vGuide ); - Rtl_LibUpdateBoxes( p ); - Rtl_LibReorderModules( p ); + int iNtk1 = iNtk >> 16; + int iNtk2 = iNtk & 0xFFFF; + Rtl_Ntk_t * pNtk1 = Rtl_LibNtk(p, iNtk1); + Rtl_Ntk_t * pNtk2 = Rtl_LibNtk(p, iNtk2); + assert( iNtk1 != iNtk2 ); + if ( fInv ) + { + printf( "Setting \"%s\" (appearing %d times) and \"%s\" (appearing %d times) as inverse-equivalent.\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + if ( p->vInverses == NULL ) + p->vInverses = Vec_IntAlloc( 10 ); + Vec_IntPushTwo( p->vInverses, pNtk1->NameId, pNtk2->NameId ); + } + else + { + printf( "Replacing \"%s\" (appearing %d times) by \"%s\" (appearing %d times).\n", + Rtl_NtkName(pNtk1), Rtl_LibCountInsts(p, pNtk1), Rtl_NtkName(pNtk2), Rtl_LibCountInsts(p, pNtk2) ); + pNtk1->iCopy = iNtk2; + // Rtl_LibSetReplace( p, vGuide ); + Rtl_LibUpdateBoxes( p ); + Rtl_LibReorderModules( p ); + if ( p->vDirects == NULL ) + p->vDirects = Vec_IntAlloc( 10 ); + Vec_IntPushTwo( p->vDirects, pNtk1->NameId, pNtk2->NameId ); + } } } } From 5999b5a516a2256bcd30007f0cdaf7971118bd46 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Apr 2022 17:49:39 -0700 Subject: [PATCH 54/74] Adding switch -c to &cone. --- src/base/abci/abc.c | 17 ++++++++++++++--- src/base/wln/wlnRead.c | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 46b2215a8..78c4f556a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -44051,9 +44051,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) { Gia_Man_t * pTemp; Vec_Int_t * vPos; - int c, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fVerbose = 0; + int c, nRegs = 0, iOutNum = -1, nOutRange = 1, iPartNum = -1, nLevelMax = 0, nTimeWindow = 0, fUseAllCis = 0, fExtractAll = 0, fComb = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaevh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORPLWaecvh" ) ) != EOF ) { switch ( c ) { @@ -44118,6 +44118,9 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'e': fExtractAll ^= 1; break; + case 'c': + fComb ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -44181,20 +44184,27 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameUpdateGia( pAbc, pTemp ); return 0; } + nRegs = Gia_ManRegNum( pAbc->pGia ); + if ( fComb ) + Gia_ManSetRegNum( pAbc->pGia, 0 ); if ( iOutNum < 0 || iOutNum + nOutRange > Gia_ManPoNum(pAbc->pGia) ) { Abc_Print( -1, "Abc_CommandAbc9Cone(): Range of outputs to extract is incorrect.\n" ); + if ( fComb ) + Gia_ManSetRegNum( pAbc->pGia, nRegs ); return 1; } vPos = Vec_IntStartRange( iOutNum, nOutRange ); pTemp = Gia_ManDupCones( pAbc->pGia, Vec_IntArray(vPos), nOutRange, !fUseAllCis ); + if ( fComb ) + Gia_ManSetRegNum( pAbc->pGia, nRegs ); Vec_IntFree( vPos ); if ( pTemp ) Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &cone [-ORPLW num] [-aevh]\n" ); + Abc_Print( -2, "usage: &cone [-ORPLW num] [-aecvh]\n" ); Abc_Print( -2, "\t extracting multi-output sequential logic cones\n" ); Abc_Print( -2, "\t-O num : the index of first PO to extract [default = %d]\n", iOutNum ); Abc_Print( -2, "\t-R num : (optional) the number of outputs to extract [default = %d]\n", nOutRange ); @@ -44203,6 +44213,7 @@ usage: Abc_Print( -2, "\t-W num : (optional) extract cones falling into this window [default = %d]\n", nTimeWindow ); Abc_Print( -2, "\t-a : toggle keeping all CIs or structral support only [default = %s]\n", fUseAllCis? "all": "structural" ); Abc_Print( -2, "\t-e : toggle writing all outputs into individual files [default = %s]\n", fExtractAll? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle performing cone extraction combinationally [default = %s]\n", fComb? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index cd868185e..276683aa6 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -2776,7 +2776,7 @@ void Wln_LibGraftOne( Rtl_Lib_t * p, char ** pModules, int nModules, int fInv, i { int iNtk1 = Rtl_LibFindModule(p, iName1); int iNtk2 = Rtl_LibFindModule(p, iName2); - Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); + //Rtl_Ntk_t * pNtk1 = Rtl_LibNtk( p, iNtk1 ); Rtl_Ntk_t * pNtk2 = Rtl_LibNtk( p, iNtk2 ); pNtk2->iCopy = iNtk1; } From daa4eaf2af1bab7330a1f8daf607789f84bfe4e2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Apr 2022 18:54:12 -0700 Subject: [PATCH 55/74] Removing duplicated command. --- src/base/wlc/wlcCom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index dcddd0423..e981e0fa2 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -88,7 +88,7 @@ void Wlc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Word level", "%memabs2", Abc_CommandMemAbs2, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blast", Abc_CommandBlast, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%blastmem", Abc_CommandBlastMem, 0 ); - Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); +// Cmd_CommandAdd( pAbc, "Word level", "%graft", Abc_CommandGraft, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%retime", Abc_CommandRetime, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%profile", Abc_CommandProfile, 0 ); Cmd_CommandAdd( pAbc, "Word level", "%short_names", Abc_CommandShortNames, 0 ); From f6758079f7b2d9bd95275d2a7f59bdf9c661232e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 27 Apr 2022 20:54:04 -0700 Subject: [PATCH 56/74] Removing equivalence classes when they are not properly refined. --- src/proof/cec/cecCorr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proof/cec/cecCorr.c b/src/proof/cec/cecCorr.c index 8614ab072..d1d8958fc 100644 --- a/src/proof/cec/cecCorr.c +++ b/src/proof/cec/cecCorr.c @@ -1054,6 +1054,8 @@ int Cec_ManLSCorrespondenceClasses( Gia_Man_t * pAig, Cec_ParCor_t * pPars ) printf( "Iterative refinement is stopped after iteration %d\n", r ); printf( "because refinement does not proceed quickly.\n" ); Cec_ManSimStop( pSim ); + ABC_FREE( pAig->pReprs ); + ABC_FREE( pAig->pNexts ); return 0; } nPrev[0] = nPrev[1]; From 61f2f3db6f154360930eb16f7d54f97165ef5d05 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 28 Apr 2022 15:41:02 -0700 Subject: [PATCH 57/74] Removing equivalence classes when they are not properly refined. --- src/aig/gia/giaMini.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 6cc528f2b..448706bfd 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -764,7 +764,10 @@ int * Abc_FrameReadMiniAigEquivClasses( Abc_Frame_t * pAbc ) if ( pAbc->pGia2 == NULL ) printf( "Internal GIA with equivalence classes is not available.\n" ); if ( pAbc->pGia2->pReprs == NULL ) + { printf( "Equivalence classes of internal GIA are not available.\n" ); + return NULL; + } if ( Gia_ManObjNum(pAbc->pGia2) != Gia_ManObjNum(pAbc->pGiaMiniAig) ) printf( "Internal GIA with equivalence classes is not directly derived from MiniAig.\n" ); // derive the set of equivalent node pairs From 3d19d411b2417752cc3e64cd93cb7649f29e7276 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 18 May 2022 10:41:39 -0700 Subject: [PATCH 58/74] Improvements to MiniAIG. --- src/aig/gia/giaMini.c | 45 ++++++- src/aig/miniaig/miniaig.h | 251 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 283 insertions(+), 13 deletions(-) diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 448706bfd..f0558cc4d 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -182,13 +182,56 @@ void * Abc_FrameGiaOutputMiniAig( Abc_Frame_t * pAbc ) SeeAlso [] ***********************************************************************/ +void Gia_ManReadMiniAigNames( char * pFileName, Gia_Man_t * pGia ) +{ + char * filename3 = Abc_UtilStrsavTwo( pFileName, ".ilo" ); + FILE * pFile = fopen( filename3, "rb" ); + if ( pFile ) + { + char Buffer[5000], * pName; int i, iLines = 0; + Vec_Ptr_t * vTemp = Vec_PtrAlloc( Gia_ManRegNum(pGia) ); + assert( pGia->vNamesIn == NULL ); + pGia->vNamesIn = Vec_PtrAlloc( Gia_ManCiNum(pGia) ); + assert( pGia->vNamesOut == NULL ); + pGia->vNamesOut = Vec_PtrAlloc( Gia_ManCoNum(pGia) ); + while ( fgets(Buffer, 5000, pFile) ) + { + if ( Buffer[strlen(Buffer)-1] == '\n' ) + Buffer[strlen(Buffer)-1] = 0; + if ( iLines < Gia_ManPiNum(pGia) ) + Vec_PtrPush( pGia->vNamesIn, Abc_UtilStrsav(Buffer) ); + else if ( iLines < Gia_ManCiNum(pGia) ) + Vec_PtrPush( vTemp, Abc_UtilStrsav(Buffer) ); + else + Vec_PtrPush( pGia->vNamesOut, Abc_UtilStrsav(Buffer) ); + iLines++; + } + Vec_PtrForEachEntry( char *, vTemp, pName, i ) + { + Vec_PtrPush( pGia->vNamesIn, Abc_UtilStrsav(pName) ); + Vec_PtrPush( pGia->vNamesOut, Abc_UtilStrsavTwo(pName, "_in") ); + } + Vec_PtrFreeFree( vTemp ); + fclose( pFile ); + printf( "Read ILO names into file \"%s\".\n", filename3 ); + } + ABC_FREE( filename3 ); +} Gia_Man_t * Gia_ManReadMiniAig( char * pFileName, int fGiaSimple ) { Mini_Aig_t * p = Mini_AigLoad( pFileName ); - Gia_Man_t * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple ); + Gia_Man_t * pTemp, * pGia = Gia_ManFromMiniAig( p, NULL, fGiaSimple ); ABC_FREE( pGia->pName ); pGia->pName = Extra_FileNameGeneric( pFileName ); Mini_AigStop( p ); + Gia_ManReadMiniAigNames( pFileName, pGia ); + if ( !Gia_ManIsNormalized(pGia) ) + { + pGia = Gia_ManDupNormalize( pTemp = pGia, 0 ); + ABC_SWAP( Vec_Ptr_t *, pTemp->vNamesIn, pGia->vNamesIn ); + ABC_SWAP( Vec_Ptr_t *, pTemp->vNamesOut, pGia->vNamesOut ); + Gia_ManStop( pTemp ); + } return pGia; } void Gia_ManWriteMiniAig( Gia_Man_t * pGia, char * pFileName ) diff --git a/src/aig/miniaig/miniaig.h b/src/aig/miniaig/miniaig.h index 120611445..2573d35ba 100644 --- a/src/aig/miniaig/miniaig.h +++ b/src/aig/miniaig/miniaig.h @@ -30,7 +30,9 @@ #include #include +#ifndef _VERIFIC_DATABASE_H_ ABC_NAMESPACE_HEADER_START +#endif //////////////////////////////////////////////////////////////////////// /// PARAMETERS /// @@ -92,13 +94,13 @@ static void Mini_AigPush( Mini_Aig_t * p, int Lit0, int Lit1 ) static int Mini_AigNodeFanin0( Mini_Aig_t * p, int Id ) { assert( Id >= 0 && 2*Id < p->nSize ); - assert( p->pArray[2*Id] == 0x7FFFFFFF || p->pArray[2*Id] < 2*Id ); + assert( p->pArray[2*Id] == MINI_AIG_NULL || p->pArray[2*Id] < 2*Id ); return p->pArray[2*Id]; } static int Mini_AigNodeFanin1( Mini_Aig_t * p, int Id ) { assert( Id >= 0 && 2*Id < p->nSize ); - assert( p->pArray[2*Id+1] == 0x7FFFFFFF || p->pArray[2*Id+1] < 2*Id ); + assert( p->pArray[2*Id+1] == MINI_AIG_NULL || p->pArray[2*Id+1] < 2*Id ); return p->pArray[2*Id+1]; } @@ -170,7 +172,7 @@ static int Mini_AigAndNum( Mini_Aig_t * p ) } static void Mini_AigPrintStats( Mini_Aig_t * p ) { - printf( "PI = %d. PO = %d. Node = %d.\n", Mini_AigPiNum(p), Mini_AigPoNum(p), Mini_AigAndNum(p) ); + printf( "MiniAIG stats: PI = %d PO = %d FF = %d AND = %d\n", Mini_AigPiNum(p), Mini_AigPoNum(p), Mini_AigRegNum(p), Mini_AigAndNum(p) ); } // serialization @@ -233,7 +235,10 @@ static int Mini_AigAnd( Mini_Aig_t * p, int Lit0, int Lit1 ) int Lit = p->nSize; assert( Lit0 >= 0 && Lit0 < Lit ); assert( Lit1 >= 0 && Lit1 < Lit ); - Mini_AigPush( p, Lit0, Lit1 ); + if ( Lit0 < Lit1 ) + Mini_AigPush( p, Lit0, Lit1 ); + else + Mini_AigPush( p, Lit1, Lit0 ); return Lit; } static int Mini_AigOr( Mini_Aig_t * p, int Lit0, int Lit1 ) @@ -250,6 +255,42 @@ static int Mini_AigXor( Mini_Aig_t * p, int Lit0, int Lit1 ) { return Mini_AigMux( p, Lit0, Mini_AigLitNot(Lit1), Lit1 ); } +static int Mini_AigXorSpecial( Mini_Aig_t * p, int Lit0, int Lit1 ) +{ + int Lit = p->nSize; + assert( Lit0 >= 0 && Lit0 < Lit ); + assert( Lit1 >= 0 && Lit1 < Lit ); + if ( Lit0 > Lit1 ) + Mini_AigPush( p, Lit0, Lit1 ); + else + Mini_AigPush( p, Lit1, Lit0 ); + return Lit; +} +static int Mini_AigAndMulti( Mini_Aig_t * p, int * pLits, int nLits ) +{ + int i; + assert( nLits > 0 ); + while ( nLits > 1 ) + { + for ( i = 0; i < nLits/2; i++ ) + pLits[i] = Mini_AigAnd(p, pLits[2*i], pLits[2*i+1]); + if ( nLits & 1 ) + pLits[i++] = pLits[nLits-1]; + nLits = i; + } + return pLits[0]; +} +static int Mini_AigMuxMulti( Mini_Aig_t * p, int * pCtrl, int * pData, int nData ) +{ + int Res0, Res1; + assert( nData > 0 ); + if ( nData == 1 ) + return pData[0]; + assert( nData % 2 == 0 ); + Res0 = Mini_AigMuxMulti( p, pCtrl+1, pData, nData/2 ); + Res1 = Mini_AigMuxMulti( p, pCtrl+1, pData+nData/2, nData/2 ); + return Mini_AigMux( p, pCtrl[0], Res1, Res0 ); +} static unsigned s_MiniTruths5[5] = { 0xAAAAAAAA, @@ -340,11 +381,11 @@ static int Mini_AigCheck( Mini_Aig_t * p ) static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_t * p ) { int i, k, iFaninLit0, iFaninLit1, Length = strlen(pModuleName), nPos = Mini_AigPoNum(p); - Vec_Bit_t * vObjIsPi = Vec_BitStart( Mini_AigNodeNum(p) ); + char * pObjIsPi = MINI_AIG_CALLOC( char, Mini_AigNodeNum(p) ); FILE * pFile = fopen( pFileName, "wb" ); - if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); return; } + if ( pFile == NULL ) { printf( "Cannot open output file %s\n", pFileName ); MINI_AIG_FREE( pObjIsPi ); return; } // write interface - fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() ); + //fprintf( pFile, "// This MiniAIG dump was produced by ABC on %s\n\n", Extra_TimeStamp() ); fprintf( pFile, "module %s (\n", pModuleName ); if ( Mini_AigPiNum(p) > 0 ) { @@ -354,7 +395,7 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_ { if ( k++ % 12 == 0 ) fprintf( pFile, "\n%*s", Length+10, "" ); fprintf( pFile, "i%d, ", i ); - Vec_BitWriteEntry( vObjIsPi, i, 1 ); + pObjIsPi[i] = 1; } } fprintf( pFile, "\n%*soutput wire", Length+10, "" ); @@ -371,9 +412,9 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_ iFaninLit0 = Mini_AigNodeFanin0( p, i ); iFaninLit1 = Mini_AigNodeFanin1( p, i ); fprintf( pFile, " assign n%d = ", i ); - fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit0 >> 1) ? 'i':'n', iFaninLit0 >> 1 ); + fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", pObjIsPi[iFaninLit0 >> 1] ? 'i':'n', iFaninLit0 >> 1 ); fprintf( pFile, " & " ); - fprintf( pFile, "%s%c%d", (iFaninLit1 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit1 >> 1) ? 'i':'n', iFaninLit1 >> 1 ); + fprintf( pFile, "%s%c%d", (iFaninLit1 & 1) ? "~":"", pObjIsPi[iFaninLit1 >> 1] ? 'i':'n', iFaninLit1 >> 1 ); fprintf( pFile, ";\n" ); } // write assigns @@ -382,19 +423,205 @@ static void Mini_AigDumpVerilog( char * pFileName, char * pModuleName, Mini_Aig_ { iFaninLit0 = Mini_AigNodeFanin0( p, i ); fprintf( pFile, " assign o%d = ", i ); - fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", Vec_BitEntry(vObjIsPi, iFaninLit0 >> 1) ? 'i':'n', iFaninLit0 >> 1 ); + fprintf( pFile, "%s%c%d", (iFaninLit0 & 1) ? "~":"", pObjIsPi[iFaninLit0 >> 1] ? 'i':'n', iFaninLit0 >> 1 ); fprintf( pFile, ";\n" ); } fprintf( pFile, "\nendmodule // %s \n\n\n", pModuleName ); - Vec_BitFree( vObjIsPi ); + MINI_AIG_FREE( pObjIsPi ); fclose( pFile ); } +// checks if MiniAIG is normalized (first inputs, then internal nodes, then outputs) +static int Mini_AigIsNormalized( Mini_Aig_t * p ) +{ + int nCiNum = Mini_AigPiNum(p); + int nCoNum = Mini_AigPoNum(p); + int i, nOffset = 1; + for ( i = 0; i < nCiNum; i++ ) + if ( !Mini_AigNodeIsPi( p, nOffset+i ) ) + return 0; + nOffset = Mini_AigNodeNum(p) - nCoNum; + for ( i = 0; i < nCoNum; i++ ) + if ( !Mini_AigNodeIsPo( p, nOffset+i ) ) + return 0; + return 1; +} + + +//////////////////////////////////////////////////////////////////////// +/// MiniAIG reading from / write into AIGER /// +//////////////////////////////////////////////////////////////////////// + +static unsigned Mini_AigerReadUnsigned( FILE * pFile ) +{ + unsigned x = 0, i = 0; + unsigned char ch; + while ((ch = fgetc(pFile)) & 0x80) + x |= (ch & 0x7f) << (7 * i++); + return x | (ch << (7 * i)); +} +static void Mini_AigerWriteUnsigned( FILE * pFile, unsigned x ) +{ + unsigned char ch; + while (x & ~0x7f) + { + ch = (x & 0x7f) | 0x80; + fputc( ch, pFile ); + x >>= 7; + } + ch = x; + fputc( ch, pFile ); +} +static int * Mini_AigerReadInt( char * pFileName, int * pnObjs, int * pnIns, int * pnLatches, int * pnOuts, int * pnAnds ) +{ + int i, Temp, nTotal, nObjs, nIns, nLatches, nOuts, nAnds, * pObjs; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + fprintf( stdout, "Mini_AigerRead(): Cannot open the output file \"%s\".\n", pFileName ); + return NULL; + } + if ( fgetc(pFile) != 'a' || fgetc(pFile) != 'i' || fgetc(pFile) != 'g' ) + { + fprintf( stdout, "Mini_AigerRead(): Can only read binary AIGER.\n" ); + fclose( pFile ); + return NULL; + } + if ( fscanf(pFile, "%d %d %d %d %d", &nTotal, &nIns, &nLatches, &nOuts, &nAnds) != 5 ) + { + fprintf( stdout, "Mini_AigerRead(): Cannot read the header line.\n" ); + fclose( pFile ); + return NULL; + } + if ( nTotal != nIns + nLatches + nAnds ) + { + fprintf( stdout, "The number of objects does not match.\n" ); + fclose( pFile ); + return NULL; + } + nObjs = 1 + nIns + 2*nLatches + nOuts + nAnds; + pObjs = MINI_AIG_CALLOC( int, nObjs * 2 ); + for ( i = 0; i <= nIns + nLatches; i++ ) + pObjs[2*i] = pObjs[2*i+1] = MINI_AIG_NULL; + // read flop input literals + for ( i = 0; i < nLatches; i++ ) + { + while ( fgetc(pFile) != '\n' ); + fscanf( pFile, "%d", &Temp ); + pObjs[2*(nObjs-nLatches+i)+0] = Temp; + pObjs[2*(nObjs-nLatches+i)+1] = MINI_AIG_NULL; + } + // read output literals + for ( i = 0; i < nOuts; i++ ) + { + while ( fgetc(pFile) != '\n' ); + fscanf( pFile, "%d", &Temp ); + pObjs[2*(nObjs-nOuts-nLatches+i)+0] = Temp; + pObjs[2*(nObjs-nOuts-nLatches+i)+1] = MINI_AIG_NULL; + } + // read the binary part + while ( fgetc(pFile) != '\n' ); + for ( i = 0; i < nAnds; i++ ) + { + int uLit = 2*(1+nIns+nLatches+i); + int uLit1 = uLit - Mini_AigerReadUnsigned( pFile ); + int uLit0 = uLit1 - Mini_AigerReadUnsigned( pFile ); + pObjs[uLit+0] = uLit0; + pObjs[uLit+1] = uLit1; + } + fclose( pFile ); + if ( pnObjs ) *pnObjs = nObjs; + if ( pnIns ) *pnIns = nIns; + if ( pnLatches ) *pnLatches = nLatches; + if ( pnOuts ) *pnOuts = nOuts; + if ( pnAnds ) *pnAnds = nAnds; + return pObjs; +} +static Mini_Aig_t * Mini_AigerRead( char * pFileName, int fVerbose ) +{ + Mini_Aig_t * p; + int nObjs, nIns, nLatches, nOuts, nAnds, * pObjs = Mini_AigerReadInt( pFileName, &nObjs, &nIns, &nLatches, &nOuts, &nAnds ); + if ( pObjs == NULL ) + return NULL; + p = MINI_AIG_CALLOC( Mini_Aig_t, 1 ); + p->nCap = 2*nObjs; + p->nSize = 2*nObjs; + p->nRegs = nLatches; + p->pArray = pObjs; + if ( fVerbose ) + printf( "Loaded MiniAIG from the AIGER file \"%s\".\n", pFileName ); + return p; +} + +static void Mini_AigerWriteInt( char * pFileName, int * pObjs, int nObjs, int nIns, int nLatches, int nOuts, int nAnds ) +{ + FILE * pFile = fopen( pFileName, "wb" ); int i; + if ( pFile == NULL ) + { + fprintf( stdout, "Mini_AigerWrite(): Cannot open the output file \"%s\".\n", pFileName ); + return; + } + fprintf( pFile, "aig %d %d %d %d %d\n", nIns + nLatches + nAnds, nIns, nLatches, nOuts, nAnds ); + for ( i = 0; i < nLatches; i++ ) + fprintf( pFile, "%d\n", pObjs[2*(nObjs-nLatches+i)+0] ); + for ( i = 0; i < nOuts; i++ ) + fprintf( pFile, "%d\n", pObjs[2*(nObjs-nOuts-nLatches+i)+0] ); + for ( i = 0; i < nAnds; i++ ) + { + int uLit = 2*(1+nIns+nLatches+i); + int uLit0 = pObjs[uLit+0]; + int uLit1 = pObjs[uLit+1]; + Mini_AigerWriteUnsigned( pFile, uLit - uLit1 ); + Mini_AigerWriteUnsigned( pFile, uLit1 - uLit0 ); + } + fprintf( pFile, "c\n" ); + fclose( pFile ); +} +static void Mini_AigerWrite( char * pFileName, Mini_Aig_t * p, int fVerbose ) +{ + int i, nIns = 0, nOuts = 0, nAnds = 0; + assert( Mini_AigIsNormalized(p) ); + for ( i = 1; i < Mini_AigNodeNum(p); i++ ) + { + if ( Mini_AigNodeIsPi(p, i) ) + nIns++; + else if ( Mini_AigNodeIsPo(p, i) ) + nOuts++; + else + nAnds++; + } + Mini_AigerWriteInt( pFileName, p->pArray, p->nSize/2, nIns - p->nRegs, p->nRegs, nOuts - p->nRegs, nAnds ); + if ( fVerbose ) + printf( "Written MiniAIG into the AIGER file \"%s\".\n", pFileName ); +} +static void Mini_AigerTest( char * pFileNameIn, char * pFileNameOut ) +{ + Mini_Aig_t * p = Mini_AigerRead( pFileNameIn, 1 ); + if ( p == NULL ) + return; + printf( "Finished reading input file \"%s\".\n", pFileNameIn ); + Mini_AigerWrite( pFileNameOut, p, 1 ); + printf( "Finished writing output file \"%s\".\n", pFileNameOut ); + Mini_AigStop( p ); +} + +/* +int main( int argc, char ** argv ) +{ + if ( argc != 3 ) + return 0; + Mini_AigerTest( argv[1], argv[2] ); + return 1; +} +*/ + //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// //////////////////////////////////////////////////////////////////////// +#ifndef _VERIFIC_DATABASE_H_ ABC_NAMESPACE_HEADER_END +#endif #endif From 67247b7209967a94d84e20b77f90dbc0ef5de108 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 18 May 2022 10:42:37 -0700 Subject: [PATCH 59/74] One less line printed out in the batch mode. --- src/base/main/mainUtils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/main/mainUtils.c b/src/base/main/mainUtils.c index 377299fd1..bb6d0a310 100644 --- a/src/base/main/mainUtils.c +++ b/src/base/main/mainUtils.c @@ -160,7 +160,7 @@ void Abc_UtilsPrintUsage( Abc_Frame_t * pAbc, char * ProgName ) void Abc_UtilsSource( Abc_Frame_t * pAbc ) { #ifdef WIN32 - if ( Cmd_CommandExecute(pAbc, "source abc.rc") ) + if ( Cmd_CommandExecute(pAbc, "source -s abc.rc") ) { if ( Cmd_CommandExecute(pAbc, "source ..\\abc.rc") == 0 ) printf( "Loaded \"abc.rc\" from the parent directory.\n" ); From 21922e3e9f45023612c64753311bc2f53e59e332 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 18 May 2022 10:43:07 -0700 Subject: [PATCH 60/74] Adding switch to dsd_match to skip small functions. --- src/base/abci/abc.c | 20 +++++++++++++++----- src/base/cmd/cmdUtils.c | 2 +- src/base/wln/wlnRead.c | 1 + src/map/if/if.h | 2 +- src/map/if/ifDsd.c | 8 ++++---- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 78c4f556a..c46eb2a70 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -19704,10 +19704,10 @@ usage: int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv ) { char * pStruct = NULL; - int c, fVerbose = 0, fFast = 0, fAdd = 0, fSpec = 0, LutSize = 0, nConfls = 10000, nProcs = 1; + int c, fVerbose = 0, fFast = 0, fAdd = 0, fSpec = 0, LutSize = 0, nConfls = 10000, nProcs = 1, nInputs = 0; If_DsdMan_t * pDsdMan = (If_DsdMan_t *)Abc_FrameReadManDsd(); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "KCPSfasvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "KCPISfasvh" ) ) != EOF ) { switch ( c ) { @@ -19740,6 +19740,15 @@ int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv ) nProcs = atoi(argv[globalUtilOptind]); globalUtilOptind++; break; + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by a floating point number.\n" ); + goto usage; + } + nInputs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + break; case 'S': if ( globalUtilOptind >= argc ) { @@ -19780,18 +19789,19 @@ int Abc_CommandDsdMatch( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "DSD manager matched with cell %s should be cleaned by \"dsd_filter -m\" before matching with cell %s.\n", pStructCur, pStruct ); return 0; } - Id_DsdManTuneStr( pDsdMan, pStruct, nConfls, nProcs, fVerbose ); + Id_DsdManTuneStr( pDsdMan, pStruct, nConfls, nProcs, nInputs, fVerbose ); } else If_DsdManTune( pDsdMan, LutSize, fFast, fAdd, fSpec, fVerbose ); return 0; usage: - Abc_Print( -2, "usage: dsd_match [-KCP num] [-fasvh] [-S str]\n" ); + Abc_Print( -2, "usage: dsd_match [-KCPI num] [-fasvh] [-S str]\n" ); Abc_Print( -2, "\t matches DSD structures with the given cell\n" ); Abc_Print( -2, "\t-K num : LUT size used for tuning [default = %d]\n", LutSize ); Abc_Print( -2, "\t-C num : the maximum number of conflicts [default = %d]\n", nConfls ); Abc_Print( -2, "\t-P num : the maximum number of processes [default = %d]\n", nProcs ); + Abc_Print( -2, "\t-I num : skip checking if support is less than this [default = %d]\n", nInputs ); Abc_Print( -2, "\t-f : toggles using fast check [default = %s]\n", fFast? "yes": "no" ); Abc_Print( -2, "\t-a : toggles adding tuning to the current one [default = %s]\n", fAdd? "yes": "no" ); Abc_Print( -2, "\t-s : toggles using specialized check [default = %s]\n", fSpec? "yes": "no" ); @@ -44186,7 +44196,7 @@ int Abc_CommandAbc9Cone( Abc_Frame_t * pAbc, int argc, char ** argv ) } nRegs = Gia_ManRegNum( pAbc->pGia ); if ( fComb ) - Gia_ManSetRegNum( pAbc->pGia, 0 ); + pAbc->pGia->nRegs = 0; if ( iOutNum < 0 || iOutNum + nOutRange > Gia_ManPoNum(pAbc->pGia) ) { Abc_Print( -1, "Abc_CommandAbc9Cone(): Range of outputs to extract is incorrect.\n" ); diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c index 3409543f1..835e939b0 100644 --- a/src/base/cmd/cmdUtils.c +++ b/src/base/cmd/cmdUtils.c @@ -459,7 +459,7 @@ FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFi else { // print the path/name of the resource file 'abc.rc' that is being loaded - if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 ) + if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 ) Abc_Print( 1, "Loading resource file \"%s\".\n", sRealName ); } } diff --git a/src/base/wln/wlnRead.c b/src/base/wln/wlnRead.c index 276683aa6..a27d38d2d 100644 --- a/src/base/wln/wlnRead.c +++ b/src/base/wln/wlnRead.c @@ -2733,6 +2733,7 @@ Gia_Man_t * Rtl_LibCollapse( Rtl_Lib_t * p, char * pTopModule, int fVerbose ) Vec_IntPush( vRoots, iNtk ); Rtl_LibBlast2( p, vRoots, 1 ); pGia = Gia_ManDup( pTop->pGia ); + //Gia_AigerWrite( pGia, "temp_miter.aig", 0, 0, 0 ); if ( pTop->pGia->vBarBufs ) pGia->vBarBufs = Vec_IntDup( pTop->pGia->vBarBufs ); printf( "Derived global AIG for the top module \"%s\". ", Rtl_NtkStr(pTop, NameId) ); diff --git a/src/map/if/if.h b/src/map/if/if.h index aa9608c9c..3c2ba7034 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -564,7 +564,7 @@ extern If_DsdMan_t * If_DsdManAlloc( int nVars, int nLutSize ); extern void If_DsdManAllocIsops( If_DsdMan_t * p, int nLutSize ); extern void If_DsdManPrint( If_DsdMan_t * p, char * pFileName, int Number, int Support, int fOccurs, int fTtDump, int fVerbose ); extern void If_DsdManTune( If_DsdMan_t * p, int LutSize, int fFast, int fAdd, int fSpec, int fVerbose ); -extern void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int fVerbose ); +extern void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int nInputs, int fVerbose ); extern void If_DsdManFree( If_DsdMan_t * p, int fVerbose ); extern void If_DsdManSave( If_DsdMan_t * p, char * pFileName ); extern If_DsdMan_t * If_DsdManLoad( char * pFileName ); diff --git a/src/map/if/ifDsd.c b/src/map/if/ifDsd.c index ddfc10365..d33c42d64 100644 --- a/src/map/if/ifDsd.c +++ b/src/map/if/ifDsd.c @@ -2554,7 +2554,7 @@ void Id_DsdManTuneStr1( If_DsdMan_t * p, char * pStruct, int nConfls, int fVerbo ***********************************************************************/ #ifndef ABC_USE_PTHREADS -void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int fVerbose ) +void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int nInputs, int fVerbose ) { Id_DsdManTuneStr1( p, pStruct, nConfls, fVerbose ); } @@ -2600,7 +2600,7 @@ void * Ifn_WorkerThread( void * pArg ) assert( 0 ); return NULL; } -void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int fVerbose ) +void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, int nInputs, int fVerbose ) { int fVeryVerbose = 0; ProgressBar * pProgress = NULL; @@ -2703,8 +2703,8 @@ void Id_DsdManTuneStr( If_DsdMan_t * p, char * pStruct, int nConfls, int nProcs, Extra_ProgressBarUpdate( pProgress, k, NULL ); pObj = If_DsdVecObj( &p->vObjs, k ); nVars = If_DsdObjSuppSize(pObj); - //if ( nVars <= LutSize ) - // continue; + if ( nInputs && nVars < nInputs ) + continue; clk = Abc_Clock(); If_DsdManComputeTruthPtr( p, Abc_Var2Lit(k, 0), NULL, ThData[i].pTruth ); clkUsed += Abc_Clock() - clk; From 4f7bf9100399a3a25d51d4fd8d6b0bf7cd9ed3ed Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 20 May 2022 12:53:12 -0700 Subject: [PATCH 61/74] Adding new switch to &cec. --- src/base/abci/abc.c | 32 ++++++++++++++++++++++++-------- src/proof/cec/cecSatG3.c | 11 +++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index c46eb2a70..7cabe3c61 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -37774,10 +37774,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) FILE * pFile; Gia_Man_t * pGias[2] = {NULL, NULL}, * pMiter; char ** pArgvNew; - int c, nArgcNew, fUseSim = 0, fUseNew = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; + int c, nArgcNew, fUseSim = 0, fUseNewX = 0, fUseNewY = 0, fMiter = 0, fDualOutput = 0, fDumpMiter = 0; Cec_ManCecSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxtvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "CTnmdasxytvwh" ) ) != EOF ) { switch ( c ) { @@ -37819,7 +37819,10 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) pPars->fSilent ^= 1; break; case 'x': - fUseNew ^= 1; + fUseNewX ^= 1; + break; + case 'y': + fUseNewY ^= 1; break; case 't': fUseSim ^= 1; @@ -37985,12 +37988,12 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManAppendCi(pGias0); Gia_ManAppendCi(pGias1); } - pMiter = Gia_ManMiter( pGias0, pGias1, 0, !fUseNew, 0, 0, pPars->fVerbose ); + pMiter = Gia_ManMiter( pGias0, pGias1, 0, !fUseNewX && !fUseNewY, 0, 0, pPars->fVerbose ); Gia_ManStop( pGias0 ); Gia_ManStop( pGias1 ); } else - pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNew, 0, 0, pPars->fVerbose ); + pMiter = Gia_ManMiter( pGias[0], pGias[1], 0, !fUseNewX && !fUseNewY, 0, 0, pPars->fVerbose ); if ( pMiter ) { @@ -38022,7 +38025,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Networks are UNDECIDED. " ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } - else if ( fUseNew ) + else if ( fUseNewX ) { abctime clk = Abc_Clock(); extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); @@ -38034,6 +38037,18 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); Gia_ManStop( pNew ); } + else if ( fUseNewY ) + { + abctime clk = Abc_Clock(); + extern Gia_Man_t * Cec5_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ); + Gia_Man_t * pNew = Cec5_ManSimulateTest3( pMiter, pPars->nBTLimit, pPars->fVerbose ); + if ( Gia_ManAndNum(pNew) == 0 ) + Abc_Print( 1, "Networks are equivalent. " ); + else + Abc_Print( 1, "Networks are UNDECIDED. " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_ManStop( pNew ); + } else { pAbc->Status = Cec_ManVerify( pMiter, pPars ); @@ -38047,7 +38062,7 @@ int Abc_CommandAbc9Cec( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxtvwh]\n" ); + Abc_Print( -2, "usage: &cec [-CT num] [-nmdasxytvwh]\n" ); Abc_Print( -2, "\t new combinational equivalence checker\n" ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); Abc_Print( -2, "\t-T num : approximate runtime limit in seconds [default = %d]\n", pPars->TimeLimit ); @@ -38056,7 +38071,8 @@ usage: Abc_Print( -2, "\t-d : toggle using dual output miter [default = %s]\n", fDualOutput? "yes":"no"); Abc_Print( -2, "\t-a : toggle writing dual-output miter [default = %s]\n", fDumpMiter? "yes":"no"); Abc_Print( -2, "\t-s : toggle silent operation [default = %s]\n", pPars->fSilent ? "yes":"no"); - Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNew? "yes":"no"); + Abc_Print( -2, "\t-x : toggle using new solver [default = %s]\n", fUseNewX? "yes":"no"); + Abc_Print( -2, "\t-y : toggle using new solver [default = %s]\n", fUseNewY? "yes":"no"); Abc_Print( -2, "\t-t : toggle using simulation [default = %s]\n", fUseSim? "yes":"no"); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes":"no"); Abc_Print( -2, "\t-w : toggle printing SAT solver statistics [default = %s]\n", pPars->fVeryVerbose? "yes":"no"); diff --git a/src/proof/cec/cecSatG3.c b/src/proof/cec/cecSatG3.c index 5f22937c2..f8e3ad0a0 100644 --- a/src/proof/cec/cecSatG3.c +++ b/src/proof/cec/cecSatG3.c @@ -2321,6 +2321,17 @@ int Cec5_ManSweepNodeCbs( Cec5_Man_t * p, CbsP_Man_t * pCbs, int iObj, int iRepr } return RetValue; } +Gia_Man_t * Cec5_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose ) +{ + int fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500; + Gia_Man_t * pNew = NULL; + Cec_ParFra_t ParsFra, * pPars = &ParsFra; + Cec5_ManSetParams( pPars ); + pPars->fVerbose = fVerbose; + pPars->nBTLimit = nBTLimit; + Cec5_ManPerformSweeping( p, pPars, &pNew, 0, fCbs, approxLim, subBatchSz, adaRecycle ); + return pNew; +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// From 5a3e0a1f15cf4299470c81fdf314f22ea2f37fa7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 22 May 2022 19:47:13 -0700 Subject: [PATCH 62/74] Improvements to MiniAIG. --- src/aig/miniaig/miniaig.h | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/aig/miniaig/miniaig.h b/src/aig/miniaig/miniaig.h index 2573d35ba..c501d326e 100644 --- a/src/aig/miniaig/miniaig.h +++ b/src/aig/miniaig/miniaig.h @@ -280,18 +280,37 @@ static int Mini_AigAndMulti( Mini_Aig_t * p, int * pLits, int nLits ) } return pLits[0]; } -static int Mini_AigMuxMulti( Mini_Aig_t * p, int * pCtrl, int * pData, int nData ) +static int Mini_AigMuxMulti( Mini_Aig_t * p, int * pCtrl, int nCtrl, int * pData, int nData ) +{ + int i, c; + assert( nData > 0 ); + if ( nCtrl == 0 ) + return pData[0]; + assert( nData <= (1 << nCtrl) ); + for ( c = 0; c < nCtrl; c++ ) + { + for ( i = 0; i < nData/2; i++ ) + pData[i] = Mini_AigMux( p, pCtrl[c], pData[2*i+1], pData[2*i] ); + if ( nData & 1 ) + pData[i++] = Mini_AigMux( p, pCtrl[c], 0, pData[nData-1] ); + nData = i; + } + assert( nData == 1 ); + return pData[0]; +} +static int Mini_AigMuxMulti_rec( Mini_Aig_t * p, int * pCtrl, int * pData, int nData ) { int Res0, Res1; assert( nData > 0 ); if ( nData == 1 ) return pData[0]; assert( nData % 2 == 0 ); - Res0 = Mini_AigMuxMulti( p, pCtrl+1, pData, nData/2 ); - Res1 = Mini_AigMuxMulti( p, pCtrl+1, pData+nData/2, nData/2 ); + Res0 = Mini_AigMuxMulti_rec( p, pCtrl+1, pData, nData/2 ); + Res1 = Mini_AigMuxMulti_rec( p, pCtrl+1, pData+nData/2, nData/2 ); return Mini_AigMux( p, pCtrl[0], Res1, Res0 ); } + static unsigned s_MiniTruths5[5] = { 0xAAAAAAAA, 0xCCCCCCCC, From 94ab17c39e847a2326138068fadfe52c3675f70b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Jun 2022 07:47:33 -0700 Subject: [PATCH 63/74] Supporting new resub problem format. --- src/aig/gia/giaUtil.c | 50 ++++++++++++++++++++++++- src/base/io/io.c | 53 +++++++++++++++++++++++++++ src/base/main/mainUtils.c | 2 +- src/misc/util/utilTruth.h | 18 +++++++++ src/misc/vec/vecInt.h | 2 + src/proof/acec/acecBo.c | 77 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 200 insertions(+), 2 deletions(-) diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index 431be5b7e..d81305507 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -3080,7 +3080,55 @@ Gia_Man_t * Gia_ManTransformCond( Gia_Man_t * p ) Abc_PrintTime( 0, "Time", Abc_Clock() - clk ); return NULL; } - +void Gia_ManWriteSol( Gia_Man_t * p, char * pFileName ) +{ + char * pBasicName = Extra_FileNameGeneric( pFileName ); + char * pFileName2 = Abc_UtilStrsavTwo( pBasicName, ".sol" ); + FILE * pFile = fopen( pFileName2, "wb" ); + ABC_FREE( pBasicName ); + if ( pFile == NULL ) + printf( "Cannot open output file \"%s\".\n", pFileName2 ); + else + { + Gia_Obj_t * pObj; int i; + Gia_ManForEachAnd( p, pObj, i ) + fprintf( pFile, "%d %d ", Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) ); + Gia_ManForEachCo( p, pObj, i ) + fprintf( pFile, "%d %d ", Gia_ObjFaninLit0p(p, pObj), Gia_ObjFaninLit0p(p, pObj) ); + fclose( pFile ); + printf( "Finished writing solution file \"%s\".\n", pFileName2 ); + } + ABC_FREE( pFileName2 ); +} +void Gia_ManWriteResub( Gia_Man_t * p, char * pFileName ) +{ + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open output file \"%s\".\n", pFileName ); + else + { + Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) ); + Vec_Wrd_t * vSimsPo = Gia_ManSimPatSimOut( p, vSimsPi, 1 ); + int i, k, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p); + word * pTemp = ABC_ALLOC( word, nWords ); + fprintf( pFile, "%d %d %d %d\n", Gia_ManCiNum(p), 0, Gia_ManCoNum(p), 1 << Gia_ManCiNum(p) ); + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + Abc_TtPrintBinary1( pFile, Vec_WrdEntryP(vSimsPi, i*nWords), Gia_ManCiNum(p) ), fprintf(pFile, "\n"); + for ( i = 0; i < (1 << Gia_ManCoNum(p)); i++ ) + { + Abc_TtFill( pTemp, nWords ); + for ( k = 0; k < Gia_ManCoNum(p); k++ ) + Abc_TtAndCompl( pTemp, pTemp, 0, Vec_WrdEntryP(vSimsPo, k*nWords), !((i>>k)&1), nWords ); + Abc_TtPrintBinary1( pFile, pTemp, Gia_ManCiNum(p) ), fprintf(pFile, "\n"); + } + ABC_FREE( pTemp ); + fclose( pFile ); + Vec_WrdFree( vSimsPi ); + Vec_WrdFree( vSimsPo ); + printf( "Finished writing resub file \"%s\".\n", pFileName ); + Gia_ManWriteSol( p, pFileName ); + } +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/io/io.c b/src/base/io/io.c index 26bfb1f4a..9b3d288a4 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -84,6 +84,7 @@ static int IoCommandWriteTruths ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteStatus ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteSmv ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteJson ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandWriteResub ( Abc_Frame_t * pAbc, int argc, char **argv ); extern void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk ); @@ -155,6 +156,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "write_status", IoCommandWriteStatus, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_smv", IoCommandWriteSmv, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_json", IoCommandWriteJson, 0 ); + Cmd_CommandAdd( pAbc, "I/O", "&write_resub", IoCommandWriteResub, 0 ); } /**Function************************************************************* @@ -3480,6 +3482,57 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IoCommandWriteResub( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + extern void Gia_ManWriteResub( Gia_Man_t * p, char * pFileName ); + char * pFileName; + int c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "ch" ) ) != EOF ) + { + switch ( c ) + { + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + goto usage; + pFileName = argv[globalUtilOptind]; + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "IoCommandWriteResub(): There is no AIG.\n" ); + return 1; + } + if ( Gia_ManCiNum(pAbc->pGia) > 20 ) + { + Abc_Print( -1, "IoCommandWriteResub(): The number of inputs is wrong.\n" ); + return 1; + } + Gia_ManWriteResub( pAbc->pGia, pFileName ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: &write_resub [-ch] \n" ); + fprintf( pAbc->Err, "\t write the network in resub format\n" ); + fprintf( pAbc->Err, "\t-h : print the help message\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write (extension .json)\n" ); + return 1; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/main/mainUtils.c b/src/base/main/mainUtils.c index bb6d0a310..377299fd1 100644 --- a/src/base/main/mainUtils.c +++ b/src/base/main/mainUtils.c @@ -160,7 +160,7 @@ void Abc_UtilsPrintUsage( Abc_Frame_t * pAbc, char * ProgName ) void Abc_UtilsSource( Abc_Frame_t * pAbc ) { #ifdef WIN32 - if ( Cmd_CommandExecute(pAbc, "source -s abc.rc") ) + if ( Cmd_CommandExecute(pAbc, "source abc.rc") ) { if ( Cmd_CommandExecute(pAbc, "source ..\\abc.rc") == 0 ) printf( "Loaded \"abc.rc\" from the parent directory.\n" ); diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index d9efa55f6..bc8ac3f08 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -1471,6 +1471,24 @@ static inline void Abc_TtPrintBinary( word * pTruth, int nVars ) printf( "%d", Abc_InfoHasBit( (unsigned *)pThis, k ) ); printf( "\n" ); } +static inline void Abc_TtPrintBinary1( FILE * pFile, word * pTruth, int nVars ) +{ + word * pThis, * pLimit = pTruth + Abc_TtWordNum(nVars); + int k, Limit = Abc_MinInt( 64, (1 << nVars) ); + assert( nVars >= 2 ); + for ( pThis = pTruth; pThis < pLimit; pThis++ ) + for ( k = 0; k < Limit; k++ ) + fprintf( pFile, "%d", Abc_InfoHasBit( (unsigned *)pThis, k ) ); +} +static inline void Abc_TtPrintBinary2( FILE * pFile, word * pTruth, int nVars ) +{ + word * pThis; + int k, Limit = Abc_MinInt( 64, (1 << nVars) ); + assert( nVars >= 2 ); + for ( pThis = pTruth + Abc_TtWordNum(nVars) - 1; pThis >= pTruth; pThis-- ) + for ( k = Limit-1; k >= 0; k-- ) + fprintf( pFile, "%d", Abc_InfoHasBit( (unsigned *)pThis, k ) ); +} /**Function************************************************************* diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index c15369d29..e4ea6cfe3 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -61,6 +61,8 @@ struct Vec_Int_t_ for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) #define Vec_IntForEachEntryReverse( vVec, pEntry, i ) \ for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- ) +#define Vec_IntForEachEntryReverseStart( vVec, pEntry, i, Start ) \ + for ( i = Start; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- ) #define Vec_IntForEachEntryTwo( vVec1, vVec2, Entry1, Entry2, i ) \ for ( i = 0; (i < Vec_IntSize(vVec1)) && (((Entry1) = Vec_IntEntry(vVec1, i)), 1) && (((Entry2) = Vec_IntEntry(vVec2, i)), 1); i++ ) #define Vec_IntForEachEntryTwoStart( vVec1, vVec2, Entry1, Entry2, i, Start ) \ diff --git a/src/proof/acec/acecBo.c b/src/proof/acec/acecBo.c index 9cddcd132..51af02143 100644 --- a/src/proof/acec/acecBo.c +++ b/src/proof/acec/acecBo.c @@ -21,6 +21,7 @@ #include "acecInt.h" #include "misc/vec/vecWec.h" #include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -207,6 +208,82 @@ void Acec_DetectBoothTest( Gia_Man_t * p ) } } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManResubTest4() +{ + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + unsigned T = 0xF335ACC0; + int a, b, c; + int i, k, f, y; + int Count = 0; + for ( a = 0; a < 2; a++ ) + { + unsigned A = s_Truths5[a]; + for ( b = 0; b < 3; b++ ) + { + unsigned B = s_Truths5[2+b]; + for ( c = 0; c < 3; c++ ) if ( c != b ) + { + unsigned C = s_Truths5[2+c]; + Vec_IntPush( vRes, A & B & C ); + Vec_IntPush( vRes, A & B & ~C ); + } + } + } + printf( "Size = %d.\n", Vec_IntSize(vRes) ); + for ( i = 0; i < (1 << Vec_IntSize(vRes)); i++ ) + { + unsigned F[7] = {0}; + unsigned Y[3] = {0}; + if ( Abc_TtCountOnes( (word)i ) >= 8 ) + continue; + for ( f = k = 0; k < Vec_IntSize(vRes); k++ ) + if ( ((i >> k) & 1) ) + F[f++] = Vec_IntEntry(vRes, k); + { + unsigned S1 = (F[0] & F[1]) | (F[0] & F[2]) | (F[1] & F[2]); + unsigned C1 = F[0] ^ F[1] ^ F[2]; + unsigned S2 = (F[3] & F[4]) | (F[3] & F[5]) | (F[4] & F[5]); + unsigned C2 = F[3] ^ F[4] ^ F[5]; + unsigned S3 = (F[6] & S1) | (F[6] & S2) | (S1 & S2); + unsigned C3 = F[6] ^ S1 ^ S2; + unsigned S4 = (C1 & C2) | (C1 & C3) | (C2 & C3); + unsigned C4 = C1 ^ C2 ^ C3; + Y[0] = S3; + Y[1] = S4; + Y[2] = C4; + } + for ( y = 0; y < 3; y++ ) + if ( Y[y] == T ) + printf( "Found!\n" ); + Count++; + } + printf( "Tried = %d.\n", Count ); + Vec_IntFree( vRes ); +} +void Gia_ManResubTest5() +{ + unsigned T = 0xF335ACC0; + int i; + for ( i = 0; i < 4; i++ ) + { + unsigned x = i%2 ? Abc_Tt5Cofactor1(T, 0) : Abc_Tt5Cofactor0(T, 0); + unsigned y = i/2 ? Abc_Tt5Cofactor1(x, 1) : Abc_Tt5Cofactor0(x, 1); + word F = y; + F |= F << 32; + //Dau_DsdPrintFromTruth2( &F, 6 ); printf( "\n" ); + } +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From aebf1e7b9c531c7907263cb573d8ff2d1a55cebd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Jun 2022 09:35:06 -0700 Subject: [PATCH 64/74] Integrated Kissat, by Armin Biere, as an external binary. --- src/base/abci/abc.c | 113 ++++++++++++++++++++++++++++++++++++++++ src/base/cmd/cmdUtils.c | 78 +++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 7cabe3c61..a68c5de01 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -337,6 +337,7 @@ static int Abc_CommandXSat ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandSatoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Satoko ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sat3 ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Kissat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandPSat ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1084,6 +1085,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Verification", "satoko", Abc_CommandSatoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "&satoko", Abc_CommandAbc9Satoko, 0 ); Cmd_CommandAdd( pAbc, "Verification", "&sat3", Abc_CommandAbc9Sat3, 0 ); + Cmd_CommandAdd( pAbc, "Verification", "&kissat", Abc_CommandAbc9Kissat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "psat", Abc_CommandPSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "iprove", Abc_CommandIProve, 1 ); @@ -25876,6 +25878,117 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Kissat( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Mf_ManDumpCnf( Gia_Man_t * p, char * pFileName, int nLutSize, int fCnfObjIds, int fAddOrCla, int fVerbose ); + extern void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int nConfs, int nTimeLimit, int fSat, int fUnsat, int fPrintCex, int fVerbose ); + int c, nConfs = 0, nTimeLimit = 0, fSat = 0, fUnsat = 0, fPrintCex = 0, fVerbose = 0; + char * pArgs = NULL; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "CTAsucvh" ) ) != EOF ) + { + switch ( c ) + { + case 'C': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-C\" should be followed by an integer.\n" ); + goto usage; + } + nConfs = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nConfs < 0 ) + goto usage; + break; + case 'T': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-T\" should be followed by an integer.\n" ); + goto usage; + } + nTimeLimit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nTimeLimit < 0 ) + goto usage; + break; + case 'A': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-A\" should be followed by a file name.\n" ); + goto usage; + } + pArgs = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 's': + fSat ^= 1; + break; + case 'u': + fUnsat ^= 1; + break; + case 'c': + fPrintCex ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + + default: + goto usage; + } + } + if ( argc == globalUtilOptind + 1 ) + { + Gia_ManKissatCall( pAbc, argv[globalUtilOptind], pArgs, nConfs, nTimeLimit, fSat, fUnsat, fPrintCex, fVerbose ); + return 0; + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9Satoko(): There is no AIG.\n" ); + return 1; + } + else + { + int nLutSize = 8; + int fCnfObjIds = 0; + int fAddOrCla = 1; + char * pFileName = "_temp_.cnf"; + Mf_ManDumpCnf( pAbc->pGia, pFileName, nLutSize, fCnfObjIds, fAddOrCla, fVerbose ); + Gia_ManKissatCall( pAbc, pFileName, pArgs, nConfs, nTimeLimit, fSat, fUnsat, fPrintCex, fVerbose ); + unlink( pFileName ); + } + return 0; + +usage: + Abc_Print( -2, "usage: &kissat [-CT num] [-sucvh] [-A string] \n" ); + Abc_Print( -2, "\t run SAT solver Kissat, by Armin Biere (https://github.com/arminbiere/kissat)\n" ); + Abc_Print( -2, "\t-C num : limit on the number of conflicts [default = %d]\n", nConfs ); + Abc_Print( -2, "\t-T num : runtime limit in seconds [default = %d]\n", nTimeLimit ); + Abc_Print( -2, "\t-s : expect a satisfiable problem [default = %s]\n", fSat ? "yes": "no" ); + Abc_Print( -2, "\t-u : expect an unsatisfiable problem [default = %s]\n", fUnsat ? "yes": "no" ); + Abc_Print( -2, "\t-c : prints satisfying assignment if satisfiable [default = %s]\n", fPrintCex ? "yes": "no" ); + Abc_Print( -2, "\t-v : prints verbose information [default = %s]\n", fVerbose ? "yes": "no" ); + Abc_Print( -2, "\t-A num : string containing additional command-line args for the Kissat binary [default = %s]\n", pArgs ? pArgs : "unused" ); + Abc_Print( -2, "\t (in particular, <&kissat -A \"--help\"> prints all command-line args of Kissat)\n" ); + Abc_Print( -2, "\t : (optional) CNF file to solve\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c index 835e939b0..cf26c0c7c 100644 --- a/src/base/cmd/cmdUtils.c +++ b/src/base/cmd/cmdUtils.c @@ -20,6 +20,7 @@ #include "base/abc/abc.h" #include "base/main/mainInt.h" +#include "misc/util/utilSignal.h" #include "cmdInt.h" #include @@ -749,6 +750,83 @@ void CmdPrintTable( st__table * tTable, int fAliases ) ABC_FREE( ppNames ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int nConfs, int nTimeLimit, int fSat, int fUnsat, int fPrintCex, int fVerbose ) +{ + char Command[1000], Buffer[100]; + char * pNameWin = "kissat.exe"; + char * pNameUnix = "kissat"; + char * pKissatName = NULL; + FILE * pFile = NULL; + + // get the names from the resource file + if ( Cmd_FlagReadByName(pAbc, "kissatwin") ) + pNameWin = Cmd_FlagReadByName(pAbc, "kissatwin"); + if ( Cmd_FlagReadByName(pAbc, "kissatunix") ) + pNameUnix = Cmd_FlagReadByName(pAbc, "kissatunix"); + + // check if the binary is available + if ( (pFile = fopen( pNameWin, "r" )) ) + pKissatName = pNameWin; + else if ( (pFile = fopen( pNameUnix, "r" )) ) + pKissatName = pNameUnix; + else if ( pFile == NULL ) + { + fprintf( stdout, "Cannot find Kissat binary \"%s\" or \"%s\" in the current directory.\n", pNameWin, pNameUnix ); + return; + } + fclose( pFile ); + + sprintf( Command, "%s", pKissatName ); + if ( pArgs ) + { + strcat( Command, " " ); + strcat( Command, pArgs ); + } + if ( !pArgs || (strcmp(pArgs, "-h") && strcmp(pArgs, "--help")) ) + { + if ( !fVerbose ) + strcat( Command, " -q" ); + if ( !fPrintCex ) + strcat( Command, " -n" ); + if ( fSat ) + strcat( Command, " --sat" ); + if ( fUnsat ) + strcat( Command, " --unsat" ); + if ( nConfs ) + { + sprintf( Buffer, " --conflicts=%d", nConfs ); + strcat( Command, Buffer ); + } + if ( nTimeLimit ) + { + sprintf( Buffer, " --time=%d", nTimeLimit ); + strcat( Command, Buffer ); + } + strcat( Command, " " ); + strcat( Command, pFileName ); + } + if ( fVerbose ) + printf( "Running command: %s\n", Command ); + if ( Util_SignalSystem( Command ) == -1 ) + { + fprintf( stdout, "The following command has returned a strange exit status:\n" ); + fprintf( stdout, "\"%s\"\n", Command ); + } +} + + + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 617eb759ae67b7fc839322639ab97cc6200e53af Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Jun 2022 18:27:40 -0700 Subject: [PATCH 65/74] Enabling support for reading AIGs with XOR gates. --- src/aig/gia/giaMuxes.c | 67 ++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaSimBase.c | 8 ++++- src/base/abci/abc.c | 22 ++++++++++--- 3 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/aig/gia/giaMuxes.c b/src/aig/gia/giaMuxes.c index 7b3aa54c3..ff542c305 100644 --- a/src/aig/gia/giaMuxes.c +++ b/src/aig/gia/giaMuxes.c @@ -147,6 +147,73 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit ) return pNew; } +/**Function************************************************************* + + Synopsis [Creates AIG with XORs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCreateXors( Gia_Man_t * p ) +{ + Gia_Man_t * pNew; Gia_Obj_t * pObj, * pFan0, * pFan1; + Vec_Int_t * vRefs = Vec_IntStart( Gia_ManObjNum(p) ); + int i, iLit0, iLit1, nXors = 0, nObjs = 0; + Gia_ManForEachObj( p, pObj, i ) + pObj->fMark0 = 0; + Gia_ManForEachAnd( p, pObj, i ) + { + if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) ) + { + Vec_IntAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pFan0)), 1 ); + Vec_IntAddToEntry( vRefs, Gia_ObjId(p, Gia_Regular(pFan1)), 1 ); + pObj->fMark0 = 1; + nXors++; + } + else + { + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0(pObj, i), 1 ); + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId1(pObj, i), 1 ); + } + } + Gia_ManForEachCo( p, pObj, i ) + Vec_IntAddToEntry( vRefs, Gia_ObjFaninId0p(p, pObj), 1 ); + Gia_ManForEachAnd( p, pObj, i ) + nObjs += Vec_IntEntry(vRefs, i) > 0; + pNew = Gia_ManStart( 1 + Gia_ManCiNum(p) + Gia_ManCoNum(p) + nObjs ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( Gia_ObjIsBuf(pObj) ) + pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + else if ( pObj->fMark0 ) + { + Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1); + iLit0 = Abc_LitNotCond( Gia_Regular(pFan0)->Value, Gia_IsComplement(pFan0) ); + iLit1 = Abc_LitNotCond( Gia_Regular(pFan1)->Value, Gia_IsComplement(pFan1) ); + pObj->Value = Gia_ManAppendXorReal( pNew, iLit0, iLit1 ); + } + else if ( Vec_IntEntry(vRefs, i) > 0 ) + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + } + assert( pNew->nObjs == pNew->nObjsAlloc ); + pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjs ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vRefs ); + //printf( "Created %d XORs.\n", nXors ); + return pNew; +} + /**Function************************************************************* Synopsis [Derives GIA without MUXes.] diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c index c8808532d..002f6bc2d 100644 --- a/src/aig/gia/giaSimBase.c +++ b/src/aig/gia/giaSimBase.c @@ -2485,15 +2485,21 @@ void Gia_ManSimGen( Gia_Man_t * pGia ) SeeAlso [] ***********************************************************************/ -int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose ) +int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int TimeLimit, int fVerbose ) { Vec_Wrd_t * vSim0, * vSim1, * vSim2; abctime clk = Abc_Clock(); int n, i, RetValue = 1; + int TimeStop = TimeLimit ? TimeLimit * CLOCKS_PER_SEC + Abc_Clock() : 0; // in CPU ticks printf( "Simulating %d round with %d machine words.\n", nRounds, nWords ); Abc_RandomW(0); for ( n = 0; RetValue && n < nRounds; n++ ) { + if ( TimeStop && Abc_Clock() > TimeStop ) + { + printf( "Computation timed out after %d seconds and %d rounds.\n", TimeLimit, n ); + break; + } vSim0 = Vec_WrdStartRandom( Gia_ManCiNum(p0) * nWords ); p0->vSimsPi = vSim0; p1->vSimsPi = vSim0; diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index a68c5de01..71f8cad5e 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -30138,6 +30138,7 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) extern void Abc3_ReadShowHie( char * pFileName, int fFlat ); extern Gia_Man_t * Gia_MiniAigSuperDerive( char * pFileName, int fVerbose ); extern Gia_Man_t * Gia_FileSimpleRead( char * pFileName, int fNames, char * pFileW ); + extern Gia_Man_t * Gia_ManCreateXors( Gia_Man_t * p ); Gia_Man_t * pAig = NULL; FILE * pFile; char ** pArgvNew; @@ -30150,8 +30151,9 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) int fGiaSimple = 0; int fSkipStrash = 0; int fNewReader = 0; + int fDetectXors = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "csmnlpvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "csxmnlpvh" ) ) != EOF ) { switch ( c ) { @@ -30161,6 +30163,9 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) case 's': fSkipStrash ^= 1; break; + case 'x': + fDetectXors ^= 1; + break; case 'm': fMiniAig ^= 1; break; @@ -30215,16 +30220,25 @@ int Abc_CommandAbc9Read( Abc_Frame_t * pAbc, int argc, char ** argv ) // else if ( Extra_FileIsType( FileName, ".v", NULL, NULL ) ) // Abc3_ReadShowHie( FileName, fSkipStrash ); else + { pAig = Gia_AigerRead( FileName, fGiaSimple, fSkipStrash, 0 ); + if ( fDetectXors ) + { + Gia_Man_t * pTemp; + pAig = Gia_ManCreateXors( pTemp = pAig ); + Gia_ManStop( pTemp ); + } + } if ( pAig ) Abc_FrameUpdateGia( pAbc, pAig ); return 0; usage: - Abc_Print( -2, "usage: &r [-csmnlvh] \n" ); + Abc_Print( -2, "usage: &r [-csxmnlvh] \n" ); Abc_Print( -2, "\t reads the current AIG from the AIGER file\n" ); Abc_Print( -2, "\t-c : toggles reading simple AIG [default = %s]\n", fGiaSimple? "yes": "no" ); Abc_Print( -2, "\t-s : toggles structural hashing while reading [default = %s]\n", !fSkipStrash? "yes": "no" ); + Abc_Print( -2, "\t-x : toggles detecting XORs while reading [default = %s]\n", fDetectXors? "yes": "no" ); Abc_Print( -2, "\t-m : toggles reading MiniAIG rather than AIGER file [default = %s]\n", fMiniAig? "yes": "no" ); Abc_Print( -2, "\t-n : toggles reading MiniAIG as a set of supergates [default = %s]\n", fMiniAig2? "yes": "no" ); Abc_Print( -2, "\t-l : toggles reading MiniLUT rather than AIGER file [default = %s]\n", fMiniLut? "yes": "no" ); @@ -32979,7 +32993,7 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int fVerbose ); + extern int Gia_ManSimTwo( Gia_Man_t * p0, Gia_Man_t * p1, int nWords, int nRounds, int TimeLimit, int fVerbose ); Gia_Man_t * pGias[2]; FILE * pFile; char ** pArgvNew; int nArgcNew; int c, RetValue = 0, fVerbose = 0, nWords = 16, nRounds = 10, RandSeed = 1, TimeLimit = 0; @@ -33126,7 +33140,7 @@ int Abc_CommandAbc9Sim2( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "The number of COs does not match.\n" ); return 1; } - RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, fVerbose ); + RetValue = Gia_ManSimTwo( pGias[0], pGias[1], nWords, nRounds, TimeLimit, fVerbose ); if ( pGias[0] != pAbc->pGia ) Gia_ManStopP( &pGias[0] ); Gia_ManStopP( &pGias[1] ); From 7bda1d4bfb4f927b04e7b1c03b34eaef5dd88ee8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Jun 2022 18:28:51 -0700 Subject: [PATCH 66/74] Renaming switch '-i' into '-c' in %collapse. --- src/base/wln/wlnCom.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/base/wln/wlnCom.c b/src/base/wln/wlnCom.c index 0314fff32..eb96132b4 100644 --- a/src/base/wln/wlnCom.c +++ b/src/base/wln/wlnCom.c @@ -336,7 +336,7 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) char * pTopModule = NULL; int c, fInv = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Tivh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Tcvh" ) ) != EOF ) { switch ( c ) { @@ -349,7 +349,7 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) pTopModule = argv[globalUtilOptind]; globalUtilOptind++; break; - case 'i': + case 'c': fInv ^= 1; break; case 'v': @@ -372,10 +372,10 @@ int Abc_CommandCollapse( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: %%collapse [-T ] [-ivh] \n" ); + Abc_Print( -2, "usage: %%collapse [-T ] [-cvh] \n" ); Abc_Print( -2, "\t collapse hierarchical design into an AIG\n" ); Abc_Print( -2, "\t-T : specify the top module of the design [default = none]\n" ); - Abc_Print( -2, "\t-i : toggle complementing miter outputs after collapsing [default = %s]\n", fInv? "yes": "no" ); + Abc_Print( -2, "\t-c : toggle complementing miter outputs after collapsing [default = %s]\n", fInv? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; From 3241a595bab1601a26a10d6452dbd205b2c1480f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Jun 2022 08:50:37 -0700 Subject: [PATCH 67/74] Bug fix by Ai Quoc Dao. --- src/base/abci/abcTiming.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c index 84cda931f..1341630bd 100644 --- a/src/base/abci/abcTiming.c +++ b/src/base/abci/abcTiming.c @@ -608,7 +608,7 @@ void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew ) } if ( pNtkOld->pManTime->tOutLoad ) { - pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtkOld) ); + pNtkNew->pManTime->tOutLoad = ABC_ALLOC( Abc_Time_t, Abc_NtkCoNum(pNtkOld) ); memcpy( pNtkNew->pManTime->tOutLoad, pNtkOld->pManTime->tOutLoad, sizeof(Abc_Time_t) * Abc_NtkCoNum(pNtkOld) ); } From ae0f03f4a953a98540d67bc64846a492c568c70d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Jun 2022 14:06:23 -0700 Subject: [PATCH 68/74] Adding command to check resub problem solution. --- abclib.dsp | 4 + src/aig/gia/giaResub6.c | 403 ++++++++++++++++++++++++++++++++++++++++ src/aig/gia/giaSupps.c | 104 +++++++++++ src/aig/gia/module.make | 1 + src/base/abci/abc.c | 60 ++++++ 5 files changed, 572 insertions(+) create mode 100644 src/aig/gia/giaResub6.c diff --git a/abclib.dsp b/abclib.dsp index cf6e46e8f..33a2df6f2 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5155,6 +5155,10 @@ SOURCE=.\src\aig\gia\giaResub3.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaResub6.c +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaRetime.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaResub6.c b/src/aig/gia/giaResub6.c new file mode 100644 index 000000000..567bf30be --- /dev/null +++ b/src/aig/gia/giaResub6.c @@ -0,0 +1,403 @@ +/**CFile**************************************************************** + + FileName [giaResub6.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Resubstitution.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaResub6.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#define MAX_NODE 100 + +typedef struct Res6_Man_t_ Res6_Man_t; +struct Res6_Man_t_ +{ + int nIns; // inputs + int nDivs; // divisors + int nDivsA; // divisors alloc + int nOuts; // outputs + int nPats; // patterns + int nWords; // words + Vec_Wrd_t vIns; // input sim data + Vec_Wrd_t vOuts; // input sim data + word ** ppLits; // literal sim info + word ** ppSets; // set sim info + Vec_Int_t vSol; // current solution + Vec_Int_t vSolBest; // best solution + Vec_Int_t vTempBest;// current best solution +}; + +extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit ); + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Res6_Man_t * Res6_ManStart( int nIns, int nNodes, int nOuts, int nPats ) +{ + Res6_Man_t * p; int i; + p = ABC_CALLOC( Res6_Man_t, 1 ); + p->nIns = nIns; + p->nDivs = 1 + nIns + nNodes; + p->nDivsA = p->nDivs + MAX_NODE; + p->nOuts = nOuts; + p->nPats = nPats; + p->nWords =(nPats + 63)/64; + Vec_WrdFill( &p->vIns, 2*p->nDivsA*p->nWords, 0 ); + Vec_WrdFill( &p->vOuts, (1 << nOuts)*p->nWords, 0 ); + p->ppLits = ABC_CALLOC( word *, 2*p->nDivsA ); + p->ppSets = ABC_CALLOC( word *, 1 << nOuts ); + for ( i = 0; i < 2*p->nDivsA; i++ ) + p->ppLits[i] = Vec_WrdEntryP( &p->vIns, i*p->nWords ); + for ( i = 0; i < (1 << nOuts); i++ ) + p->ppSets[i] = Vec_WrdEntryP( &p->vOuts, i*p->nWords ); + Abc_TtFill( p->ppLits[1], p->nWords ); + Vec_IntGrow( &p->vSol, 2*MAX_NODE+nOuts ); + Vec_IntGrow( &p->vSolBest, 2*MAX_NODE+nOuts ); + Vec_IntGrow( &p->vTempBest, 2*MAX_NODE+nOuts ); + return p; +} +static inline void Res6_ManStop( Res6_Man_t * p ) +{ + Vec_WrdErase( &p->vIns ); + Vec_WrdErase( &p->vOuts ); + Vec_IntErase( &p->vSol ); + Vec_IntErase( &p->vSolBest ); + Vec_IntErase( &p->vTempBest ); + ABC_FREE( p->ppLits ); + ABC_FREE( p->ppSets ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Res6_Man_t * Res6_ManRead( char * pFileName ) +{ + Res6_Man_t * p = NULL; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + printf( "Cannot open input file \"%s\".\n", pFileName ); + else + { + int i, k, nIns, nNodes, nOuts, nPats, iLit = 0; + char Temp[100], Buffer[100]; + char * pLine = fgets( Buffer, 100, pFile ); + if ( pLine == NULL ) + { + printf( "Cannot read the header line of input file \"%s\".\n", pFileName ); + return NULL; + } + if ( 5 != sscanf(pLine, "%s %d %d %d %d", Temp, &nIns, &nNodes, &nOuts, &nPats) ) + { + printf( "Cannot read the parameters from the header of input file \"%s\".\n", pFileName ); + return NULL; + } + p = Res6_ManStart( nIns, nNodes, nOuts, nPats ); + pLine = ABC_ALLOC( char, nPats + 100 ); + for ( i = 1; i < p->nDivs; i++ ) + { + char * pNext = fgets( pLine, nPats + 100, pFile ); + if ( pNext == NULL ) + { + printf( "Cannot read line %d of input file \"%s\".\n", i, pFileName ); + Res6_ManStop( p ); + ABC_FREE( pLine ); + fclose( pFile ); + return NULL; + } + for ( k = 0; k < p->nPats; k++ ) + if ( pNext[k] == '0' ) + Abc_TtSetBit( p->ppLits[2*i+1], k ); + else if ( pNext[k] == '1' ) + Abc_TtSetBit( p->ppLits[2*i], k ); + } + for ( i = 0; i < (1 << p->nOuts); i++ ) + { + char * pNext = fgets( pLine, nPats + 100, pFile ); + if ( pNext == NULL ) + { + printf( "Cannot read line %d of input file \"%s\".\n", i, pFileName ); + Res6_ManStop( p ); + ABC_FREE( pLine ); + fclose( pFile ); + return NULL; + } + for ( k = 0; k < p->nPats; k++ ) + if ( pNext[k] == '1' ) + Abc_TtSetBit( p->ppSets[i], k ); + } + ABC_FREE( pLine ); + fclose( pFile ); + } + return p; +} +void Res6_ManWrite( char * pFileName, Res6_Man_t * p ) +{ + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open output file \"%s\".\n", pFileName ); + else + { + int i, k; + fprintf( pFile, "resyn %d %d %d %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats ); + for ( i = 1; i < p->nDivs; i++, fputc('\n', pFile) ) + for ( k = 0; k < p->nPats; k++ ) + if ( Abc_TtGetBit(p->ppLits[2*i+1], k) ) + fputc( '0', pFile ); + else if ( Abc_TtGetBit(p->ppLits[2*i], k) ) + fputc( '1', pFile ); + else + fputc( '-', pFile ); + for ( i = 0; i < (1 << p->nOuts); i++, fputc('\n', pFile) ) + for ( k = 0; k < p->nPats; k++ ) + fputc( '0' + Abc_TtGetBit(p->ppSets[i], k), pFile ); + fclose( pFile ); + } +} +void Res6_ManPrintProblem( Res6_Man_t * p, int fVerbose ) +{ + int i, nInputs = (p->nIns && p->nIns < 6) ? p->nIns : 6; + printf( "Problem: In = %d Div = %d Out = %d Pattern = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats ); + if ( !fVerbose ) + return; + printf( "%02d : %s\n", 0, "const0" ); + printf( "%02d : %s\n", 1, "const1" ); + for ( i = 1; i < p->nDivs; i++ ) + { + if ( nInputs < 6 ) + { + *p->ppLits[2*i+0] = Abc_Tt6Stretch( *p->ppLits[2*i+0], nInputs ); + *p->ppLits[2*i+1] = Abc_Tt6Stretch( *p->ppLits[2*i+1], nInputs ); + } + printf("%02d : ", 2*i+0), Dau_DsdPrintFromTruth2(p->ppLits[2*i+0], nInputs), printf( "\n" ); + printf("%02d : ", 2*i+1), Dau_DsdPrintFromTruth2(p->ppLits[2*i+1], nInputs), printf( "\n" ); + } + for ( i = 0; i < (1 << p->nOuts); i++ ) + { + if ( nInputs < 6 ) + *p->ppSets[i] = Abc_Tt6Stretch( *p->ppSets[i], nInputs ); + printf("%02d : ", i), Dau_DsdPrintFromTruth2(p->ppSets[i], nInputs), printf( "\n" ); + } +} +static inline Vec_Int_t * Res6_ManReadSol( char * pFileName ) +{ + Vec_Int_t * vRes = NULL; int Num; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + printf( "Cannot open input file \"%s\".\n", pFileName ); + else + { + while ( fgetc(pFile) != '\n' ); + vRes = Vec_IntAlloc( 10 ); + while ( fscanf(pFile, "%d", &Num) == 1 ) + Vec_IntPush( vRes, Num ); + fclose ( pFile ); + } + return vRes; +} +static inline void Res6_ManWriteSol( char * pFileName, Vec_Int_t * p ) +{ + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open output file \"%s\".\n", pFileName ); + else + { + int i, iLit; + Vec_IntForEachEntry( p, iLit, i ) + fprintf( pFile, "%d ", iLit ); + fclose ( pFile ); + } +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Res6_LitSign( int iLit ) +{ + return Abc_LitIsCompl(iLit) ? '~' : ' '; +} +static inline int Res6_LitChar( int iLit, int nDivs ) +{ + return Abc_Lit2Var(iLit) < nDivs ? (nDivs < 28 ? 'a'+Abc_Lit2Var(iLit)-1 : 'd') : 'x'; +} +static inline void Res6_LitPrint( int iLit, int nDivs ) +{ + if ( iLit < 2 ) + printf( "%d", iLit ); + else + { + printf( "%c%c", Res6_LitSign(iLit), Res6_LitChar(iLit, nDivs) ); + if ( Abc_Lit2Var(iLit) >= nDivs || nDivs >= 28 ) + printf( "%d", Abc_Lit2Var(iLit) ); + } +} +void Res6_PrintSolution( Vec_Int_t * vSol, int nDivs ) +{ + int iNode, nNodes = Vec_IntSize(vSol)/2-1; + assert( Vec_IntSize(vSol) % 2 == 0 ); + printf( "Solution: In+Div = %d Node = %d Out = %d\n", nDivs-1, nNodes, 1 ); + for ( iNode = 0; iNode <= nNodes; iNode++ ) + { + int * pLits = Vec_IntEntryP( vSol, 2*iNode ); + printf( "x%-2d = ", nDivs + iNode ); + Res6_LitPrint( pLits[0], nDivs ); + if ( pLits[0] != pLits[1] ) + { + printf( " %c ", pLits[0] < pLits[1] ? '&' : '^' ); + Res6_LitPrint( pLits[1], nDivs ); + } + printf( "\n" ); + } +} +int Res6_FindGetCost( Res6_Man_t * p, int iDiv ) +{ + int w, Cost = 0; + //printf( "DivLit = %d\n", iDiv ); + //Abc_TtPrintBinary1( stdout, p->ppLits[iDiv], p->nIns ); printf( "\n" ); + //printf( "Set0\n" ); + //Abc_TtPrintBinary1( stdout, p->ppSets[0], p->nIns ); printf( "\n" ); + //printf( "Set1\n" ); + //Abc_TtPrintBinary1( stdout, p->ppSets[1], p->nIns ); printf( "\n" ); + for ( w = 0; w < p->nWords; w++ ) + Cost += Abc_TtCountOnes( (p->ppLits[iDiv][w] & p->ppSets[0][w]) | (p->ppLits[iDiv^1][w] & p->ppSets[1][w]) ); + return Cost; +} +int Res6_FindBestDiv( Res6_Man_t * p, int * pCost ) +{ + int d, dBest = -1, CostBest = ABC_INFINITY; + for ( d = 0; d < 2*p->nDivs; d++ ) + { + int Cost = Res6_FindGetCost( p, d ); + printf( "Div = %d Cost = %d\n", d, Cost ); + if ( CostBest >= Cost ) + CostBest = Cost, dBest = d; + } + if ( pCost ) + *pCost = CostBest; + return dBest; +} +int Res6_FindBestEval( Res6_Man_t * p, Vec_Int_t * vSol, int Start ) +{ + int i, iLit0, iLit1; + assert( Vec_IntSize(vSol) % 2 == 0 ); + Vec_IntForEachEntryDoubleStart( vSol, iLit0, iLit1, i, 2*Start ) + { + if ( iLit0 > iLit1 ) + { + Abc_TtXor( p->ppLits[2*p->nDivs+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 ); + Abc_TtXor( p->ppLits[2*p->nDivs+i+1], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 1 ); + } + else + { + Abc_TtAnd( p->ppLits[2*p->nDivs+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 ); + Abc_TtOr ( p->ppLits[2*p->nDivs+i+1], p->ppLits[iLit0^1], p->ppLits[iLit1^1], p->nWords ); + } + + //printf( "Node %d\n", i/2 ); + //Abc_TtPrintBinary1( stdout, p->ppLits[2*p->nDivs+i+0], 6 ); printf( "\n" ); + //Abc_TtPrintBinary1( stdout, p->ppLits[2*p->nDivs+i+1], 6 ); printf( "\n" ); + } + return Res6_FindGetCost( p, Vec_IntEntryLast(vSol) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Res6_ManResubVerify( Res6_Man_t * p, Vec_Int_t * vSol ) +{ + int Cost = Res6_FindBestEval( p, vSol, 0 ); + if ( Cost == 0 ) + printf( "Verification successful.\n" ); + else + printf( "Verification FAILED with %d errors on %d patterns.\n", Cost, p->nPats ); +} +void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose ) +{ + char FileNameSol[1000]; + if ( pFileNameSol ) + strcpy( FileNameSol, pFileNameSol ); + else + { + strcpy( FileNameSol, pFileNameRes ); + strcpy( FileNameSol + strlen(FileNameSol) - strlen(".resub"), ".sol" ); + } + { + Res6_Man_t * p = Res6_ManRead( pFileNameRes ); + Vec_Int_t * vSol = Res6_ManReadSol( FileNameSol ); + if ( p == NULL || vSol == NULL ) + return; + if ( fVerbose ) + Res6_ManPrintProblem( p, 0 ); + if ( fVerbose ) + Res6_PrintSolution( vSol, p->nDivs ); + Res6_ManResubVerify( p, vSol ); + Vec_IntFree( vSol ); + Res6_ManStop( p ); + } +} + + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c index f95d815d0..f9f5b5e66 100644 --- a/src/aig/gia/giaSupps.c +++ b/src/aig/gia/giaSupps.c @@ -138,6 +138,7 @@ int Supp_DeriveLines( Supp_Man_t * p ) { int n, i, iObj, nWords = p->nWords; int nDivWords = Abc_Bit6WordNum( Vec_IntSize(p->vCands) ); + //Vec_IntPrint( p->vCands ); for ( n = 0; n < 2; n++ ) { p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords ); @@ -656,6 +657,79 @@ int Supp_ManReconstruct( Supp_Man_t * p, int fVerbose ) return Supp_ManRandomSolution( p, iSet, fVerbose ); } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static int s_Counter = 0; + +void Supp_DeriveDumpSims( FILE * pFile, Vec_Wrd_t * vDivs, int nWords ) +{ + int i, k, nDivs = Vec_WrdSize(vDivs)/nWords; + for ( i = 0; i < nDivs; i++ ) + { + word * pSim = Vec_WrdEntryP(vDivs, i*nWords); + for ( k = 0; k < 64*nWords; k++ ) + fprintf( pFile, "%c", '0'+Abc_TtGetBit(pSim, k) ); + fprintf( pFile, "\n" ); + } +} +void Supp_DeriveDumpProb( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords ) +{ + char Buffer[100]; int nDivs = Vec_WrdSize(vDivs)/nWords; + int RetValue = sprintf( Buffer, "case01_%02d.resub", s_Counter ); + FILE * pFile = fopen( Buffer, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open output file.\n" ); + fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords ); + //fprintf( pFile, "%d %d %d %d\n", 0, nDivs, 1, 64*nWords ); + Supp_DeriveDumpSims( pFile, vDivs, nWords ); + Supp_DeriveDumpSims( pFile, vIsfs, nWords ); + fclose ( pFile ); + RetValue = 0; +} +void Supp_DeriveDumpSol( Vec_Int_t * vSet, Vec_Int_t * vRes, int nDivs ) +{ + char Buffer[100]; + int RetValue = sprintf( Buffer, "case01_%02d.sol", s_Counter ); + int i, iLit, iLitRes = -1, nSupp = Vec_IntSize(vSet); + FILE * pFile = fopen( Buffer, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open output file.\n" ); + fprintf( pFile, "sol name aig %d\n", Vec_IntSize(vRes)/2 ); + //Vec_IntPrint( vSet ); + //Vec_IntPrint( vRes ); + Vec_IntForEachEntry( vRes, iLit, i ) + { + assert( iLit != 2 && iLit != 3 ); + if ( iLit < 2 ) + iLitRes = iLit; + else if ( iLit-4 < 2*nSupp ) + { + int iDiv = Vec_IntEntry(vSet, Abc_Lit2Var(iLit-4)); + assert( iDiv >= 0 && iDiv < nDivs ); + iLitRes = Abc_Var2Lit(1+iDiv, Abc_LitIsCompl(iLit)); + } + else + iLitRes = iLit + 2*((nDivs+1)-(nSupp+2)); + fprintf( pFile, "%d ", iLitRes ); + } + if ( Vec_IntSize(vRes) & 1 ) + fprintf( pFile, "%d ", iLitRes ); + fprintf( pFile, "\n" ); + fclose( pFile ); + RetValue = 0; + printf( "Dumped solution info file \"%s\".\n", Buffer ); +} + /**Function************************************************************* Synopsis [] @@ -705,6 +779,7 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe Vec_IntForEachEntry( vSet, iObj, i ) Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) ); } + //Supp_DeriveDumpSol( vSet, vRes, Vec_WrdSize(p->vDivs[1])/p->nWords ); } return vRes; } @@ -802,11 +877,40 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * Supp_PrintOne( p, iBest ); } vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs ); + //Supp_DeriveDumpProb( vIsfs, p->vDivs[1], p->nWords ); + s_Counter++; + //Vec_IntPrint( vRes ); Supp_ManDelete( p ); // if ( vRes && Vec_IntSize(vRes) == 0 ) // Vec_IntFreeP( &vRes ); return vRes; } +void Supp_ManComputeTest( Gia_Man_t * p ) +{ + Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) ); + Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsPi, 0 ); + int i, iPoId, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p); + Vec_Wrd_t * vIsfs = Vec_WrdStart( 2*nWords ); + Vec_Int_t * vCands = Vec_IntAlloc( 4 ); + Vec_Int_t * vRes; + +// for ( i = 0; i < Gia_ManCiNum(p)+5; i++ ) + for ( i = 0; i < Gia_ManCiNum(p); i++ ) + Vec_IntPush( vCands, 1+i ); + + iPoId = Gia_ObjId(p, Gia_ManPo(p, 0)); + Abc_TtCopy( Vec_WrdEntryP(vIsfs, 0*nWords), Vec_WrdEntryP(vSims, iPoId*nWords), nWords, 1 ); + Abc_TtCopy( Vec_WrdEntryP(vIsfs, 1*nWords), Vec_WrdEntryP(vSims, iPoId*nWords), nWords, 0 ); + + vRes = Supp_ManCompute( vIsfs, vCands, NULL, vSims, NULL, nWords, p, NULL, 1, 1, 0 ); + Vec_IntPrint( vRes ); + + Vec_WrdFree( vSimsPi ); + Vec_WrdFree( vSims ); + Vec_WrdFree( vIsfs ); + Vec_IntFree( vCands ); + Vec_IntFree( vRes ); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 1cb7331c0..35fcb4df7 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -69,6 +69,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaResub.c \ src/aig/gia/giaResub2.c \ src/aig/gia/giaResub3.c \ + src/aig/gia/giaResub6.c \ src/aig/gia/giaRetime.c \ src/aig/gia/giaRex.c \ src/aig/gia/giaSatEdge.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 71f8cad5e..0b60bacaf 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -146,6 +146,7 @@ static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRestructure ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandResubstitute ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandResubCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCascade ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandExtract ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -894,6 +895,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 ); // Cmd_CommandAdd( pAbc, "Synthesis", "restructure", Abc_CommandRestructure, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "resub", Abc_CommandResubstitute, 1 ); + Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 ); // Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "extract", Abc_CommandExtract, 1 ); @@ -7791,6 +7793,64 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandResubCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose ); + char * pFileR = NULL, * pFileS = NULL; + int fVerbose = 0, c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc == globalUtilOptind + 2 ) + { + pFileR = argv[globalUtilOptind]; + pFileS = argv[globalUtilOptind+1]; + } + else if ( argc == globalUtilOptind + 1 ) + { + pFileR = argv[globalUtilOptind]; + pFileS = NULL; + } + else + { + Abc_Print( -1, "Incorrect number of command line arguments.\n" ); + return 1; + } + Res6_ManResubCheck( pFileR, pFileS, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: resub_check [-vh] \n" ); + Abc_Print( -2, "\t checks solution to a resub problem\n" ); + Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t : resub problem file name\n"); + Abc_Print( -2, "\t : (optional) solution file name\n"); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] From 8eb651c3d380168aeb752f90f16b37fff6d39142 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Jun 2022 16:55:12 -0700 Subject: [PATCH 69/74] Adding command to check resub problem solution. --- src/aig/gia/giaResub6.c | 52 +++++++++++++++++++++++++++++++++++++++-- src/aig/gia/giaSupps.c | 46 ++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/aig/gia/giaResub6.c b/src/aig/gia/giaResub6.c index 567bf30be..3203a6996 100644 --- a/src/aig/gia/giaResub6.c +++ b/src/aig/gia/giaResub6.c @@ -119,7 +119,7 @@ Res6_Man_t * Res6_ManRead( char * pFileName ) printf( "Cannot open input file \"%s\".\n", pFileName ); else { - int i, k, nIns, nNodes, nOuts, nPats, iLit = 0; + int i, k, nIns, nNodes, nOuts, nPats; char Temp[100], Buffer[100]; char * pLine = fgets( Buffer, 100, pFile ); if ( pLine == NULL ) @@ -279,11 +279,57 @@ static inline void Res6_LitPrint( int iLit, int nDivs ) printf( "%d", Abc_Lit2Var(iLit) ); } } +Vec_Int_t * Res6_FindSupport( Vec_Int_t * vSol, int nDivs ) +{ + int i, iLit; + Vec_Int_t * vSupp = Vec_IntAlloc( 10 ); + Vec_IntForEachEntry( vSol, iLit, i ) + if ( iLit >= 2 && iLit < 2*nDivs ) + Vec_IntPushUnique( vSupp, Abc_Lit2Var(iLit) ); + return vSupp; +} +void Res6_PrintSuppSims( Vec_Int_t * vSol, word ** ppLits, int nWords, int nDivs ) +{ + Vec_Int_t * vSupp = Res6_FindSupport( vSol, nDivs ); + int i, k, iObj; + Vec_IntForEachEntry( vSupp, iObj, i ) + { + for ( k = 0; k < 64*nWords; k++ ) + if ( Abc_TtGetBit(ppLits[2*iObj+1], k) ) + printf( "0" ); + else if ( Abc_TtGetBit(ppLits[2*iObj], k) ) + printf( "1" ); + else + printf( "-" ); + printf( "\n" ); + } + for ( k = 0; k < 64*nWords; k++ ) + { + Vec_IntForEachEntry( vSupp, iObj, i ) + if ( Abc_TtGetBit(ppLits[2*iObj+1], k) ) + printf( "0" ); + else if ( Abc_TtGetBit(ppLits[2*iObj+0], k) ) + printf( "1" ); + else + printf( "-" ); + printf( "\n" ); + if ( k == 9 ) + break; + } + Vec_IntFree( vSupp ); +} +int Res6_FindSupportSize( Vec_Int_t * vSol, int nDivs ) +{ + Vec_Int_t * vSupp = Res6_FindSupport( vSol, nDivs ); + int Res = Vec_IntSize(vSupp); + Vec_IntFree( vSupp ); + return Res; +} void Res6_PrintSolution( Vec_Int_t * vSol, int nDivs ) { int iNode, nNodes = Vec_IntSize(vSol)/2-1; assert( Vec_IntSize(vSol) % 2 == 0 ); - printf( "Solution: In+Div = %d Node = %d Out = %d\n", nDivs-1, nNodes, 1 ); + printf( "Solution: In = %d Div = %d Node = %d Out = %d\n", Res6_FindSupportSize(vSol, nDivs), nDivs-1, nNodes, 1 ); for ( iNode = 0; iNode <= nNodes; iNode++ ) { int * pLits = Vec_IntEntryP( vSol, 2*iNode ); @@ -386,6 +432,8 @@ void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose Res6_ManPrintProblem( p, 0 ); if ( fVerbose ) Res6_PrintSolution( vSol, p->nDivs ); + //if ( fVerbose ) + // Res6_PrintSuppSims( vSol, p->ppLits, p->nWords, p->nDivs ); Res6_ManResubVerify( p, vSol ); Vec_IntFree( vSol ); Res6_ManStop( p ); diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c index f9f5b5e66..96721d66b 100644 --- a/src/aig/gia/giaSupps.c +++ b/src/aig/gia/giaSupps.c @@ -46,6 +46,7 @@ struct Supp_Man_t_ Gia_Man_t * pGia; // used for object names // computed data Vec_Wrd_t * vDivs[2]; // simulation values + Vec_Wrd_t * vDivsC[2]; // simulation values Vec_Wrd_t * vPats[2]; // simulation values Vec_Ptr_t * vMatrix; // simulation values Vec_Wrd_t * vMask; // simulation values @@ -143,9 +144,10 @@ int Supp_DeriveLines( Supp_Man_t * p ) { p->vDivs[n] = Vec_WrdStart( 64*nWords*nDivWords ); p->vPats[n] = Vec_WrdStart( 64*nWords*nDivWords ); + //p->vDivsC[n] = Vec_WrdStart( 64*nWords*nDivWords ); if ( p->vSimsC ) Vec_IntForEachEntry( p->vCands, iObj, i ) - Abc_TtAndSharp( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n ); + Abc_TtAndSharp( Vec_WrdEntryP(p->vDivsC[n], i*nWords), Vec_WrdEntryP(p->vSimsC, iObj*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n ); else Vec_IntForEachEntry( p->vCands, iObj, i ) Abc_TtCopy( Vec_WrdEntryP(p->vDivs[n], i*nWords), Vec_WrdEntryP(p->vSims, iObj*nWords), nWords, !n ); @@ -195,6 +197,8 @@ void Supp_ManDelete( Supp_Man_t * p ) Supp_ManCleanMatrix( p ); Vec_WrdFreeP( &p->vDivs[0] ); Vec_WrdFreeP( &p->vDivs[1] ); + Vec_WrdFreeP( &p->vDivsC[0] ); + Vec_WrdFreeP( &p->vDivsC[1] ); Vec_WrdFreeP( &p->vPats[0] ); Vec_WrdFreeP( &p->vPats[1] ); Vec_PtrFreeP( &p->vMatrix ); @@ -682,10 +686,27 @@ void Supp_DeriveDumpSims( FILE * pFile, Vec_Wrd_t * vDivs, int nWords ) fprintf( pFile, "\n" ); } } +void Supp_DeriveDumpSimsC( FILE * pFile, Vec_Wrd_t * vDivs[2], int nWords ) +{ + int i, k, nDivs = Vec_WrdSize(vDivs[0])/nWords; + for ( i = 0; i < nDivs; i++ ) + { + word * pSim0 = Vec_WrdEntryP(vDivs[0], i*nWords); + word * pSim1 = Vec_WrdEntryP(vDivs[1], i*nWords); + for ( k = 0; k < 64*nWords; k++ ) + if ( Abc_TtGetBit(pSim0, k) ) + fprintf( pFile, "0" ); + else if ( Abc_TtGetBit(pSim1, k) ) + fprintf( pFile, "1" ); + else + fprintf( pFile, "-" ); + fprintf( pFile, "\n" ); + } +} void Supp_DeriveDumpProb( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords ) { char Buffer[100]; int nDivs = Vec_WrdSize(vDivs)/nWords; - int RetValue = sprintf( Buffer, "case01_%02d.resub", s_Counter ); + int RetValue = sprintf( Buffer, "%02d.resub", s_Counter ); FILE * pFile = fopen( Buffer, "wb" ); if ( pFile == NULL ) printf( "Cannot open output file.\n" ); @@ -696,10 +717,24 @@ void Supp_DeriveDumpProb( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords ) fclose ( pFile ); RetValue = 0; } +void Supp_DeriveDumpProbC( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs[2], int nWords ) +{ + char Buffer[100]; int nDivs = Vec_WrdSize(vDivs[0])/nWords; + int RetValue = sprintf( Buffer, "%02d.resub", s_Counter ); + FILE * pFile = fopen( Buffer, "wb" ); + if ( pFile == NULL ) + printf( "Cannot open output file.\n" ); + fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords ); + //fprintf( pFile, "%d %d %d %d\n", 0, nDivs, 1, 64*nWords ); + Supp_DeriveDumpSimsC( pFile, vDivs, nWords ); + Supp_DeriveDumpSims( pFile, vIsfs, nWords ); + fclose ( pFile ); + RetValue = 0; +} void Supp_DeriveDumpSol( Vec_Int_t * vSet, Vec_Int_t * vRes, int nDivs ) { char Buffer[100]; - int RetValue = sprintf( Buffer, "case01_%02d.sol", s_Counter ); + int RetValue = sprintf( Buffer, "%02d.sol", s_Counter ); int i, iLit, iLitRes = -1, nSupp = Vec_IntSize(vSet); FILE * pFile = fopen( Buffer, "wb" ); if ( pFile == NULL ) @@ -779,7 +814,10 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe Vec_IntForEachEntry( vSet, iObj, i ) Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) ); } + //Supp_DeriveDumpProbC( p->vIsfs, p->vDivsC, p->nWords ); + //Supp_DeriveDumpProb( p->vIsfs, p->vDivs[1], p->nWords ); //Supp_DeriveDumpSol( vSet, vRes, Vec_WrdSize(p->vDivs[1])/p->nWords ); + //s_Counter++; } return vRes; } @@ -877,8 +915,6 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * Supp_PrintOne( p, iBest ); } vRes = Supp_ManFindBestSolution( p, p->vSolutions, fVerbose, pvDivs ); - //Supp_DeriveDumpProb( vIsfs, p->vDivs[1], p->nWords ); - s_Counter++; //Vec_IntPrint( vRes ); Supp_ManDelete( p ); // if ( vRes && Vec_IntSize(vRes) == 0 ) From 8888e8e82e189a599a340e83ac8094bdef1ceb51 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 23 Jun 2022 07:48:10 -0700 Subject: [PATCH 70/74] Experiments with the mapper. --- abc.rc | 2 ++ src/bool/kit/kitDsd.c | 2 +- src/map/if/if.h | 2 ++ src/map/if/ifCore.c | 2 ++ src/map/if/ifCut.c | 62 ++++++++++++++++++++++++++++++++++++++++ src/map/if/ifMan.c | 2 ++ src/map/mio/mioUtils.c | 5 ++++ src/proof/acec/acecXor.c | 43 ++++++++++++++++++++++++++++ 8 files changed, 119 insertions(+), 1 deletion(-) diff --git a/abc.rc b/abc.rc index e50d12702..a3efc0b09 100644 --- a/abc.rc +++ b/abc.rc @@ -132,7 +132,9 @@ alias src_rw "st; rw -l; rwz -l; rwz -l" alias src_rs "st; rs -K 6 -N 2 -l; rs -K 9 -N 2 -l; rs -K 12 -N 2 -l" alias src_rws "st; rw -l; rs -K 6 -N 2 -l; rwz -l; rs -K 9 -N 2 -l; rwz -l; rs -K 12 -N 2 -l" alias resyn2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b" +alias r2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b" alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l" +alias c2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l" # use this script to convert 1-valued and DC-valued flops for an AIG alias fix_aig "logic; undc; strash; zero" diff --git a/src/bool/kit/kitDsd.c b/src/bool/kit/kitDsd.c index 7d85214ba..cd02db673 100644 --- a/src/bool/kit/kitDsd.c +++ b/src/bool/kit/kitDsd.c @@ -2497,7 +2497,7 @@ void Kit_DsdVerify( Kit_DsdNtk_t * pNtk, unsigned * pTruth, int nVars ) p = Kit_DsdManAlloc( nVars, Kit_DsdNtkObjNum(pNtk)+2 ); pTruthC = Kit_DsdTruthCompute( p, pNtk ); if ( !Extra_TruthIsEqual( pTruth, pTruthC, nVars ) ) - printf( "Verification failed.\n" ); + printf( "Verification failed for gate with %d inputs.\n", nVars ); Kit_DsdManFree( p ); } diff --git a/src/map/if/if.h b/src/map/if/if.h index 3c2ba7034..13fa41082 100644 --- a/src/map/if/if.h +++ b/src/map/if/if.h @@ -275,6 +275,8 @@ struct If_Man_t_ void * pUserMan; Vec_Int_t * vDump; int pDumpIns[16]; + Vec_Str_t * vMarks; + Vec_Int_t * vVisited2; // timing manager Tim_Man_t * pManTim; diff --git a/src/map/if/ifCore.c b/src/map/if/ifCore.c index 0c9287a19..c03061af2 100644 --- a/src/map/if/ifCore.c +++ b/src/map/if/ifCore.c @@ -106,6 +106,8 @@ int If_ManPerformMappingComb( If_Man_t * p ) If_Obj_t * pObj; abctime clkTotal = Abc_Clock(); int i; + //p->vVisited2 = Vec_IntAlloc( 100 ); + //p->vMarks = Vec_StrStart( If_ManObjNum(p) ); // set arrival times and fanout estimates If_ManForEachCi( p, pObj, i ) diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c index 2d6889c0b..079781e00 100644 --- a/src/map/if/ifCut.c +++ b/src/map/if/ifCut.c @@ -1494,6 +1494,68 @@ int If_CutCountTotalFanins( If_Man_t * p ) return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int If_CutFilter2_rec( If_Man_t * p, If_Obj_t * pObj, int LevelMin ) +{ + char * pVisited = Vec_StrEntryP(p->vMarks, pObj->Id); + if ( *pVisited ) + return *pVisited; + Vec_IntPush( p->vVisited2, pObj->Id ); + if ( (int)pObj->Level <= LevelMin ) + return (*pVisited = 1); + if ( If_CutFilter2_rec( p, pObj->pFanin0, LevelMin ) == 1 ) + return (*pVisited = 1); + if ( If_CutFilter2_rec( p, pObj->pFanin1, LevelMin ) == 1 ) + return (*pVisited = 1); + return (*pVisited = 2); +} +int If_CutFilter2( If_Man_t * p, If_Obj_t * pNode, If_Cut_t * pCut ) +{ + If_Obj_t * pLeaf, * pTemp; int i, Count = 0; +// printf( "Considering node %d and cut {", pNode->Id ); +// If_CutForEachLeaf( p, pCut, pLeaf, i ) +// printf( " %d", pLeaf->Id ); +// printf( " }\n" ); + If_CutForEachLeaf( p, pCut, pLeaf, i ) + { + int k, iObj, RetValue, nLevelMin = ABC_INFINITY; + Vec_IntClear( p->vVisited2 ); + If_CutForEachLeaf( p, pCut, pTemp, k ) + { + if ( pTemp == pLeaf ) + continue; + nLevelMin = Abc_MinInt( nLevelMin, (int)pTemp->Level ); + assert( Vec_StrEntry(p->vMarks, pTemp->Id) == 0 ); + Vec_StrWriteEntry( p->vMarks, pTemp->Id, 2 ); + Vec_IntPush( p->vVisited2, pTemp->Id ); + } + RetValue = If_CutFilter2_rec( p, pLeaf, nLevelMin ); + Vec_IntForEachEntry( p->vVisited2, iObj, k ) + Vec_StrWriteEntry( p->vMarks, iObj, 0 ); + if ( RetValue == 2 ) + { + Count++; + pCut->nLeaves--; + for ( k = i; k < (int)pCut->nLeaves; k++ ) + pCut->pLeaves[k] = pCut->pLeaves[k+1]; + i--; + } + } + //if ( Count ) + // printf( "%d", Count ); + return 0; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/map/if/ifMan.c b/src/map/if/ifMan.c index 4027b780d..6ecd0eb88 100644 --- a/src/map/if/ifMan.c +++ b/src/map/if/ifMan.c @@ -273,6 +273,8 @@ void If_ManStop( If_Man_t * p ) Vec_IntFreeP( &p->vPairRes ); Vec_StrFreeP( &p->vPairPerms ); Vec_PtrFreeP( &p->vVisited ); + Vec_StrFreeP( &p->vMarks ); + Vec_IntFreeP( &p->vVisited2 ); if ( p->vPairHash ) Hash_IntManStop( p->vPairHash ); for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ ) diff --git a/src/map/mio/mioUtils.c b/src/map/mio/mioUtils.c index c7180e1c2..06e880c24 100644 --- a/src/map/mio/mioUtils.c +++ b/src/map/mio/mioUtils.c @@ -224,6 +224,7 @@ void Mio_WritePin( FILE * pFile, Mio_Pin_t * pPin, int NameLen, int fAllPins ) ***********************************************************************/ void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen, int FormLen, int fPrintSops, int fAllPins ) { + //Vec_Int_t * vCover = Vec_IntAlloc( 1 << 10 ); int nLits; char Buffer[5000]; Mio_Pin_t * pPin; assert( NameLen+FormLen+2 < 5000 ); @@ -239,7 +240,11 @@ void Mio_WriteGate( FILE * pFile, Mio_Gate_t * pGate, int GateLen, int NameLen, else // different pins Mio_GateForEachPin( pGate, pPin ) Mio_WritePin( pFile, pPin, NameLen, 0 ); + //nLits = 2*Kit_TruthLitNum((unsigned*)&pGate->uTruth, Mio_GateReadPinNum(pGate), vCover); + //if ( nLits != Mio_GateReadArea(pGate) ) + // printf( " # %d ", nLits ); fprintf( pFile, "\n" ); + //Vec_IntFree( vCover ); } /**Function************************************************************* diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c index 71e0b7b39..963ea15b5 100644 --- a/src/proof/acec/acecXor.c +++ b/src/proof/acec/acecXor.c @@ -21,6 +21,7 @@ #include "acecInt.h" #include "misc/vec/vecWec.h" #include "misc/extra/extra.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -425,6 +426,48 @@ Acec_Box_t * Acec_ProduceBox( Gia_Man_t * p, int fVerbose ) } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestXor( Gia_Man_t * p ) +{ + Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(p) ); + Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsPi, 1 ); + int n, i, nWords = Vec_WrdSize(vSimsPi) / Gia_ManCiNum(p); + Gia_Obj_t * pObj; Vec_Wrd_t * vSims2; + Gia_ManForEachAnd( p, pObj, i ) + { + Gia_Obj_t Obj = *pObj; + for ( n = 0; n < 2; n++ ) + { + if ( n ) + { + pObj->iDiff1 = pObj->iDiff0; + pObj->fCompl1 = pObj->fCompl0; + } + else + { + pObj->iDiff0 = pObj->iDiff1; + pObj->fCompl0 = pObj->fCompl1; + } + vSims2 = Gia_ManSimPatSimOut( p, vSimsPi, 1 ); + printf( "%2d %2d : %5d\n", i, n, Abc_TtCountOnesVecXor(Vec_WrdArray(vSims), Vec_WrdArray(vSims2), Vec_WrdSize(vSims2)) ); + Vec_WrdFree( vSims2 ); + *pObj = Obj; + } + } + Vec_WrdFree( vSimsPi ); + Vec_WrdFree( vSims ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From 25455d358febbb26040916f9f90b5e2af87e1dc0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 23 Jun 2022 08:04:34 -0700 Subject: [PATCH 71/74] Making command &kissat not look for the binary in the current dir. --- src/base/cmd/cmdUtils.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c index cf26c0c7c..2158f8e97 100644 --- a/src/base/cmd/cmdUtils.c +++ b/src/base/cmd/cmdUtils.c @@ -767,14 +767,14 @@ void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int char * pNameWin = "kissat.exe"; char * pNameUnix = "kissat"; char * pKissatName = NULL; - FILE * pFile = NULL; + //FILE * pFile = NULL; // get the names from the resource file if ( Cmd_FlagReadByName(pAbc, "kissatwin") ) pNameWin = Cmd_FlagReadByName(pAbc, "kissatwin"); if ( Cmd_FlagReadByName(pAbc, "kissatunix") ) pNameUnix = Cmd_FlagReadByName(pAbc, "kissatunix"); - +/* // check if the binary is available if ( (pFile = fopen( pNameWin, "r" )) ) pKissatName = pNameWin; @@ -786,6 +786,13 @@ void Gia_ManKissatCall( Abc_Frame_t * pAbc, char * pFileName, char * pArgs, int return; } fclose( pFile ); +*/ + +#ifdef _WIN32 + pKissatName = pNameWin; +#else + pKissatName = pNameUnix; +#endif sprintf( Command, "%s", pKissatName ); if ( pArgs ) From 8cf3f54208b5cdda6a164db4a747a2e4bffcd93b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 25 Jun 2022 19:44:30 -0700 Subject: [PATCH 72/74] Experiments with technology mapping. --- abcexe.dsp | 4 + abclib.dsp | 4 + src/aig/gia/giaSif.c | 257 ++++++++++++++++++++++++++++++++++++++++ src/aig/gia/module.make | 1 + src/base/abci/abc.c | 64 ++++++++++ 5 files changed, 330 insertions(+) create mode 100644 src/aig/gia/giaSif.c diff --git a/abcexe.dsp b/abcexe.dsp index 9d5152fc2..823af19e3 100644 --- a/abcexe.dsp +++ b/abcexe.dsp @@ -88,6 +88,10 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File +SOURCE=.\src\aig\gia\giaSif.c +# End Source File +# Begin Source File + SOURCE=.\src\base\main\main.c # End Source File # End Group diff --git a/abclib.dsp b/abclib.dsp index 33a2df6f2..d536e0e72 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -5215,6 +5215,10 @@ SOURCE=.\src\aig\gia\giaShrink7.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaSif.c +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaSim.c # End Source File # Begin Source File diff --git a/src/aig/gia/giaSif.c b/src/aig/gia/giaSif.c new file mode 100644 index 000000000..d25ae5db2 --- /dev/null +++ b/src/aig/gia/giaSif.c @@ -0,0 +1,257 @@ +/**CFile**************************************************************** + + FileName [giaSif.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSif.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManCutMerge( int * pCut, int * pCut1, int * pCut2, int nSize ) +{ + int * pBeg = pCut+1; + int * pBeg1 = pCut1+1; + int * pBeg2 = pCut2+1; + int * pEnd1 = pBeg1 + pCut1[0]; + int * pEnd2 = pBeg2 + pCut2[0]; + while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 ) + { + if ( pBeg == pCut+nSize ) + { + pCut[0] = -1; + return; + } + if ( *pBeg1 == *pBeg2 ) + *pBeg++ = *pBeg1++, pBeg2++; + else if ( *pBeg1 < *pBeg2 ) + *pBeg++ = *pBeg1++; + else + *pBeg++ = *pBeg2++; + } + while ( pBeg1 < pEnd1 ) + { + if ( pBeg == pCut+nSize ) + { + pCut[0] = -1; + return; + } + *pBeg++ = *pBeg1++; + } + while ( pBeg2 < pEnd2 ) + { + if ( pBeg == pCut+nSize ) + { + pCut[0] = -1; + return; + } + *pBeg++ = *pBeg2++; + } + pCut[0] = pBeg-(pCut+1); + assert( pCut[0] < nSize ); +} +static inline int Gia_ManCutChoice( Gia_Man_t * p, int Level, int iObj, int iSibl, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize ) +{ + int * pCut = Vec_IntEntryP( vCuts, iObj*nSize ); + int * pCut2 = Vec_IntEntryP( vCuts, iSibl*nSize ); + int Level2 = Vec_IntEntry( vTimes, iSibl ); int i; + assert( iObj > iSibl ); + if ( Level < Level2 || (Level == Level2 && pCut[0] <= pCut2[0]) ) + return Level; + for ( i = 0; i <= pCut2[0]; i++ ) + pCut[i] = pCut2[i]; + return Level2; +} +static inline int Gia_ManCutOne( Gia_Man_t * p, int iObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize ) +{ + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + int iFan0 = Gia_ObjFaninId0(pObj, iObj); + int iFan1 = Gia_ObjFaninId1(pObj, iObj); + int Cut0[2] = { 1, iFan0 }; + int Cut1[2] = { 1, iFan1 }; + int * pCut = Vec_IntEntryP( vCuts, iObj*nSize ); + int * pCut0 = Vec_IntEntryP( vCuts, iFan0*nSize ); + int * pCut1 = Vec_IntEntryP( vCuts, iFan1*nSize ); + int Level_ = Vec_IntEntry( vTimes, iObj ); + int Level0 = Vec_IntEntry( vTimes, iFan0 ); + int Level1 = Vec_IntEntry( vTimes, iFan1 ); + int Level = Abc_MaxInt( Level0, Level1 ); + if ( Level == 0 ) + Level = 1; + if ( Level0 == Level1 ) + Gia_ManCutMerge( pCut, pCut0, pCut1, nSize ); + else if ( Level0 > Level1 ) + Gia_ManCutMerge( pCut, pCut0, Cut1, nSize ); + else //if ( Level0 < Level1 ) + Gia_ManCutMerge( pCut, pCut1, Cut0, nSize ); + if ( pCut[0] == -1 ) + { + pCut[0] = 2; + pCut[1] = iFan0; + pCut[2] = iFan1; + Level++; + } + if ( Gia_ObjSibl(p, iObj) ) + Level = Gia_ManCutChoice( p, Level, iObj, Gia_ObjSibl(p, iObj), vCuts, vTimes, nSize ); + assert( pCut[0] > 0 && pCut[0] < nSize ); + Vec_IntUpdateEntry( vTimes, iObj, Level ); + return Level > Level_; +} +int Gia_ManCheckIter( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period ) +{ + int i, fChange = 0, nSize = nLutSize+1; + Gia_Obj_t * pObj, * pObjRi, * pObjRo; + Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) + Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObjRo), Vec_IntEntry(vTimes, Gia_ObjId(p, pObjRi)) - Period ); + Gia_ManForEachAnd( p, pObj, i ) + fChange |= Gia_ManCutOne( p, i, vCuts, vTimes, nSize ); + Gia_ManForEachRi( p, pObj, i ) + Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) ); + return fChange; +} +int Gia_ManCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters ) +{ + Gia_Obj_t * pObj; int i; + assert( Gia_ManRegNum(p) > 0 ); + Vec_IntFill( vTimes, Gia_ManObjNum(p), -ABC_INFINITY ); + Vec_IntWriteEntry( vTimes, 0, 0 ); + Gia_ManForEachPi( p, pObj, i ) + Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 ); + for ( *pIters = 0; *pIters < 100; (*pIters)++ ) + { + if ( !Gia_ManCheckIter(p, vCuts, vTimes, nLutSize, Period) ) + return 1; + Gia_ManForEachPo( p, pObj, i ) + if ( Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) > Period ) + return 0; + } + return 0; +} +static inline void Gia_ManPrintCutOne( Gia_Man_t * p, int iObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize ) +{ + int i, * pCut = Vec_IntEntryP( vCuts, iObj*nSize ); + printf( "Obj %4d : Depth %d CutSize %d Cut {", iObj, Vec_IntEntry(vTimes, iObj), pCut[0] ); + for ( i = 1; i <= pCut[0]; i++ ) + printf( " %d", pCut[i] ); + printf( " }\n" ); +} +int Gia_ManTestMapComb( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize ) +{ + Gia_Obj_t * pObj; int i, Id, Res = 0, nSize = nLutSize+1; + Vec_IntFill( vTimes, Gia_ManObjNum(p), 0 ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntWriteEntry( vCuts, Id*nSize, 1 ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntWriteEntry( vCuts, Id*nSize+1, Id ); + Gia_ManForEachAnd( p, pObj, i ) + Gia_ManCutOne( p, i, vCuts, vTimes, nSize ); + Gia_ManForEachCo( p, pObj, i ) + Res = Abc_MaxInt( Res, Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) ); + //Gia_ManForEachAnd( p, pObj, i ) + // Gia_ManPrintCutOne( p, i, vCuts, vTimes, nSize ); + return Res; +} +void Gia_ManPrintTimes( Gia_Man_t * p, Vec_Int_t * vTimes, int Period ) +{ + int Pos[16] = {0}; + int Neg[16] = {0}; + Gia_Obj_t * pObj; int i; + Gia_ManForEachAnd( p, pObj, i ) + { + int Time = Vec_IntEntry(vTimes, i)-Period; + Time = Abc_MinInt( Time, 10*Period ); + Time = Abc_MaxInt( Time, -10*Period ); + if ( Time >= 0 ) + Pos[(Time + Period-1)/Period]++; + else + Neg[(-Time + Period-1)/Period]++; + } + printf( "Statistics: " ); + for ( i = 15; i > 0; i-- ) + if ( Neg[i] ) + printf( " -%d=%d", i, Neg[i] ); + for ( i = 0; i < 16; i++ ) + if ( Pos[i] ) + printf( " %d=%d", i, Pos[i] ); + printf( "\n" ); +} +Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose ) +{ + int nIters, nSize = nLutSize+1; // (2+1+nSize)*4=40 bytes/node + abctime clk = Abc_Clock(); + Vec_Int_t * vCuts = Vec_IntStart( Gia_ManObjNum(p) * nSize ); + Vec_Int_t * vTimes = Vec_IntAlloc( Gia_ManObjNum(p) ); + int Lower = 0; + int Upper = Gia_ManTestMapComb( p, vCuts, vTimes, nLutSize ); + if ( fVerbose && Gia_ManRegNum(p) ) + printf( "Clock period %2d is %s\n", Lower, 0 ? "Yes" : "No " ); + if ( fVerbose && Gia_ManRegNum(p) ) + printf( "Clock period %2d is %s\n", Upper, 1 ? "Yes" : "No " ); + while ( Gia_ManRegNum(p) > 0 && Upper - Lower > 1 ) + { + int Middle = (Upper + Lower) / 2; + int Status = Gia_ManCheckPeriod( p, vCuts, vTimes, nLutSize, Middle, &nIters ); + if ( Status ) + Upper = Middle; + else + Lower = Middle; + if ( fVerbose ) + printf( "Clock period %2d is %s after %d iterations\n", Middle, Status ? "Yes" : "No ", nIters ); + } + if ( fVerbose ) + printf( "Clock period = %2d ", Upper ); + if ( fVerbose ) + printf( "LUT size = %d ", nLutSize ); + if ( fVerbose ) + printf( "Memory usage = %.2f MB ", 4.0*(2+1+nSize)*Gia_ManObjNum(p)/(1 << 20) ); + if ( fVerbose ) + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + //Gia_ManCheckPeriod( p, vCuts, vTimes, nLutSize, Upper, &nIters ); + //Gia_ManPrintTimes( p, vTimes, Upper ); + Vec_IntFree( vCuts ); + Vec_IntFree( vTimes ); + return NULL; +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 35fcb4df7..171d8be30 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -84,6 +84,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaShrink.c \ src/aig/gia/giaShrink6.c \ src/aig/gia/giaShrink7.c \ + src/aig/gia/giaSif.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSim2.c \ src/aig/gia/giaSimBase.c \ diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 0b60bacaf..f1c8cc7fa 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -485,6 +485,7 @@ static int Abc_CommandAbc9If ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Iff ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Iiff ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9If2 ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9Sif ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Jf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Kf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Lf ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -1233,6 +1234,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&iff", Abc_CommandAbc9Iff, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&iiff", Abc_CommandAbc9Iiff, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&if2", Abc_CommandAbc9If2, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&sif", Abc_CommandAbc9Sif, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&jf", Abc_CommandAbc9Jf, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&kf", Abc_CommandAbc9Kf, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&lf", Abc_CommandAbc9Lf, 0 ); @@ -40202,6 +40204,68 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9Sif( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose ); + Gia_Man_t * pNew; + int c, nLutSize = 6, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by a positive integer.\n" ); + goto usage; + } + nLutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutSize < 2 || nLutSize > 16 ) + { + Abc_Print( -1, "LUT size %d is not supported.\n", nLutSize ); + goto usage; + } + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Empty GIA network.\n" ); + return 1; + } + pNew = Gia_ManTestSif( pAbc->pGia, nLutSize, fVerbose ); + if ( pNew != NULL ) + Abc_FrameUpdateGia( pAbc, pNew ); + return 0; + +usage: + Abc_Print( -2, "usage: &sif [-K num] [-vh]\n" ); + Abc_Print( -2, "\t performs technology mapping\n" ); + Abc_Print( -2, "\t-K num : sets the LUT size for the mapping [default = %d]\n", nLutSize ); + Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : prints the command usage\n"); + return 1; +} + /**Function************************************************************* Synopsis [] From adcc398bc38c91fa4cc8849aca9eb69c6fb61d21 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Jun 2022 19:45:03 -0700 Subject: [PATCH 73/74] Dumping equivalences after SAT sweeping. --- src/aig/miniaig/miniaig.h | 14 ++++ src/base/abci/abc.c | 20 ++++-- src/misc/vec/vecWrd.h | 8 +++ src/proof/acec/acecXor.c | 1 + src/proof/cec/cecSatG2.c | 135 +++++++++++++++++++++++++++++++++++++- 5 files changed, 172 insertions(+), 6 deletions(-) diff --git a/src/aig/miniaig/miniaig.h b/src/aig/miniaig/miniaig.h index c501d326e..0365b946a 100644 --- a/src/aig/miniaig/miniaig.h +++ b/src/aig/miniaig/miniaig.h @@ -368,6 +368,20 @@ static inline int Mini_AigTruth( Mini_Aig_t * p, int * pVarLits, int nVars, unsi Lit1 = Mini_AigTruth( p, pVarLits, Var, Mini_AigTt5Cofactor1(Truth, Var) ); return Mini_AigMuxProp( p, pVarLits[Var], Lit1, Lit0 ); } +static char * Mini_AigPhase( Mini_Aig_t * p ) +{ + char * pRes = MINI_AIG_CALLOC( char, Mini_AigNodeNum(p) ); + int i; + Mini_AigForEachAnd( p, i ) + { + int iFaninLit0 = Mini_AigNodeFanin0( p, i ); + int iFaninLit1 = Mini_AigNodeFanin1( p, i ); + int Phase0 = pRes[Mini_AigLit2Var(iFaninLit0)] ^ Mini_AigLitIsCompl(iFaninLit0); + int Phase1 = pRes[Mini_AigLit2Var(iFaninLit1)] ^ Mini_AigLitIsCompl(iFaninLit1); + pRes[i] = Phase0 & Phase1; + } + return pRes; +} // procedure to check the topological order during AIG construction static int Mini_AigCheck( Mini_Aig_t * p ) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index f1c8cc7fa..33a8315ca 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -37195,13 +37195,14 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) extern Gia_Man_t * Cec2_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec3_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); extern Gia_Man_t * Cec4_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars ); + extern void Cec4_ManSimulateTest5( Gia_Man_t * p, int nConfs, int fVerbose ); extern Gia_Man_t * Cec5_ManSimulateTest( Gia_Man_t * p, Cec_ParFra_t * pPars, int fCbs, int approxLim, int subBatchSz, int adaRecycle ); Cec_ParFra_t ParsFra, * pPars = &ParsFra; Gia_Man_t * pTemp; - int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0; + int c, fUseAlgo = 0, fUseAlgoG = 0, fUseAlgoX = 0, fUseAlgoY = 0, fUseSave = 0; int fCbs = 1, approxLim = 600, subBatchSz = 1, adaRecycle = 500; Cec4_ManSetParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxywvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "JWRILDCNPrmdckngxyswvh" ) ) != EOF ) { switch ( c ) { @@ -37331,6 +37332,9 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'y': fUseAlgoY ^= 1; break; + case 's': + fUseSave ^= 1; + break; case 'w': pPars->fVeryVerbose ^= 1; break; @@ -37346,7 +37350,12 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9Fraig(): There is no AIG.\n" ); return 1; } - if ( fUseAlgo ) + if ( fUseSave ) + { + Cec4_ManSimulateTest5( pAbc->pGia, pPars->nBTLimit, pPars->fVerbose ); + return 0; + } + else if ( fUseAlgo ) pTemp = Cec2_ManSimulateTest( pAbc->pGia, pPars ); else if ( fUseAlgoG ) pTemp = Cec3_ManSimulateTest( pAbc->pGia, pPars ); @@ -37354,7 +37363,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) pTemp = Cec4_ManSimulateTest( pAbc->pGia, pPars ); else if ( fUseAlgoY ) pTemp = Cec5_ManSimulateTest( pAbc->pGia, pPars, fCbs, approxLim, subBatchSz, adaRecycle ); - else + else pTemp = Cec_ManSatSweeping( pAbc->pGia, pPars, 0 ); if ( pAbc->pGia->pCexSeq != NULL ) { @@ -37366,7 +37375,7 @@ int Abc_CommandAbc9Fraig( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; usage: - Abc_Print( -2, "usage: &fraig [-JWRILDCNP ] [-rmdckngxywvh]\n" ); + Abc_Print( -2, "usage: &fraig [-JWRILDCNP ] [-rmdckngxyswvh]\n" ); Abc_Print( -2, "\t performs combinational SAT sweeping\n" ); Abc_Print( -2, "\t-J num : the solver type [default = %d]\n", pPars->jType ); Abc_Print( -2, "\t-W num : the number of simulation words [default = %d]\n", pPars->nWords ); @@ -37386,6 +37395,7 @@ usage: Abc_Print( -2, "\t-g : toggle using another new implementation [default = %s]\n", fUseAlgoG? "yes": "no" ); Abc_Print( -2, "\t-x : toggle using another new implementation [default = %s]\n", fUseAlgoX? "yes": "no" ); Abc_Print( -2, "\t-y : toggle using another new implementation [default = %s]\n", fUseAlgoY? "yes": "no" ); + Abc_Print( -2, "\t-s : toggle dumping equivalences into a file [default = %s]\n", fUseSave? "yes": "no" ); Abc_Print( -2, "\t-w : toggle printing even more verbose information [default = %s]\n", pPars->fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); diff --git a/src/misc/vec/vecWrd.h b/src/misc/vec/vecWrd.h index 8275702a4..fdbb18666 100644 --- a/src/misc/vec/vecWrd.h +++ b/src/misc/vec/vecWrd.h @@ -195,6 +195,14 @@ static inline Vec_Wrd_t * Vec_WrdStartTruthTables( int nVars ) } return p; } +static inline int Vec_WrdShiftOne( Vec_Wrd_t * p, int nWords ) +{ + int i, nObjs = p->nSize/nWords; + assert( nObjs * nWords == p->nSize ); + for ( i = 0; i < nObjs; i++ ) + p->pArray[i*nWords] <<= 1; + return nObjs; +} /**Function************************************************************* diff --git a/src/proof/acec/acecXor.c b/src/proof/acec/acecXor.c index 963ea15b5..49d0a58f2 100644 --- a/src/proof/acec/acecXor.c +++ b/src/proof/acec/acecXor.c @@ -466,6 +466,7 @@ void Gia_ManTestXor( Gia_Man_t * p ) } Vec_WrdFree( vSimsPi ); Vec_WrdFree( vSims ); + nWords = 0; } //////////////////////////////////////////////////////////////////////// diff --git a/src/proof/cec/cecSatG2.c b/src/proof/cec/cecSatG2.c index ce299c66a..2bbc03d2e 100644 --- a/src/proof/cec/cecSatG2.c +++ b/src/proof/cec/cecSatG2.c @@ -1877,9 +1877,9 @@ void Cec4_ManSimulateTest2( Gia_Man_t * p, int nConfs, int fVerbose ) abctime clk = Abc_Clock(); Cec_ParFra_t ParsFra, * pPars = &ParsFra; Cec4_ManSetParams( pPars ); - Cec4_ManPerformSweeping( p, pPars, NULL, 0 ); pPars->fVerbose = fVerbose; pPars->nBTLimit = nConfs; + Cec4_ManPerformSweeping( p, pPars, NULL, 0 ); if ( fVerbose ) Abc_PrintTime( 1, "New choice computation time", Abc_Clock() - clk ); } @@ -1912,6 +1912,139 @@ int Cec4_ManSimulateOnlyTest( Gia_Man_t * p, int fVerbose ) return Cec4_ManPerformSweeping( p, pPars, NULL, 1 ); } +/**Function************************************************************* + + Synopsis [Internal simulation APIs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cec4_ManSimulateTest5Int( Gia_Man_t * p, int nConfs, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Cec_ParFra_t ParsFra, * pPars = &ParsFra; + Cec4_ManSetParams( pPars ); + pPars->fVerbose = fVerbose; + pPars->nBTLimit = nConfs; + Cec4_ManPerformSweeping( p, pPars, NULL, 0 ); + if ( fVerbose ) + Abc_PrintTime( 1, "Equivalence detection time", Abc_Clock() - clk ); +} +Gia_Man_t * Gia_ManLocalRehash( Gia_Man_t * p ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; + int i; + pNew = Gia_ManStart( Gia_ManObjNum(p) ); + Gia_ManHashAlloc( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else if ( Gia_ObjIsCi(pObj) ) + pObj->Value = Gia_ManAppendCi( pNew ); + else if ( Gia_ObjIsCo(pObj) ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManForEachObj1( p, pObj, i ) + { + int iLitNew = Gia_ManObj(pTemp, Abc_Lit2Var(pObj->Value))->Value; + if ( iLitNew == ~0 ) + pObj->Value = iLitNew; + else + pObj->Value = Abc_LitNotCond(iLitNew, Abc_LitIsCompl(pObj->Value)); + } + Gia_ManStop( pTemp ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + return pNew; +} +Vec_Int_t * Cec4_ManComputeMapping( Gia_Man_t * p, Gia_Man_t * pAig, int fVerbose ) +{ + Gia_Obj_t * pObj; + Vec_Int_t * vReprs = Vec_IntStartFull( Gia_ManObjNum(p) ); + int * pAig2Abc = ABC_FALLOC( int, Gia_ManObjNum(pAig) ); + int i, nConsts = 0, nReprs = 0; + pAig2Abc[0] = 0; + Gia_ManForEachCand( p, pObj, i ) + { + int iLitGia = pObj->Value, iReprGia; + if ( iLitGia == -1 ) + continue; + iReprGia = Gia_ObjReprSelf( pAig, Abc_Lit2Var(iLitGia) ); + if ( pAig2Abc[iReprGia] == -1 ) + pAig2Abc[iReprGia] = i; + else + { + int iLitGia2 = Gia_ManObj(p, pAig2Abc[iReprGia] )->Value; + assert( Gia_ObjReprSelf(pAig, Abc_Lit2Var(iLitGia)) == Gia_ObjReprSelf(pAig, Abc_Lit2Var(iLitGia2)) ); + assert( i > pAig2Abc[iReprGia] ); + Vec_IntWriteEntry( vReprs, i, pAig2Abc[iReprGia] ); + if ( pAig2Abc[iReprGia] == 0 ) + nConsts++; + else + nReprs++; + } + } + ABC_FREE( pAig2Abc ); + if ( fVerbose ) + printf( "Found %d const reprs and %d other reprs.\n", nConsts, nReprs ); + return vReprs; +} +void Cec4_ManVerifyEquivs( Gia_Man_t * p, Vec_Int_t * vRes, int fVerbose ) +{ + int i, iRepr, nWords = 4; word * pSim0, * pSim1; + Vec_Wrd_t * vSimsCi = Vec_WrdStartRandom( Gia_ManCiNum(p) * nWords ); + int nObjs = Vec_WrdShiftOne( vSimsCi, nWords ), nFails = 0; + Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( p, vSimsCi, 0 ); + assert( Vec_IntSize(vRes) == Gia_ManObjNum(p) ); + assert( nObjs == Gia_ManCiNum(p) ); + Vec_IntForEachEntry( vRes, iRepr, i ) + { + if ( iRepr == -1 ) + continue; + assert( i > iRepr ); + pSim0 = Vec_WrdEntryP( vSims, nWords*i ); + pSim1 = Vec_WrdEntryP( vSims, nWords*iRepr ); + if ( (pSim0[0] ^ pSim1[0]) & 1 ) + nFails += !Abc_TtOpposite(pSim0, pSim1, nWords); + else + nFails += !Abc_TtEqual(pSim0, pSim1, nWords); + } + Vec_WrdFree( vSimsCi ); + Vec_WrdFree( vSims ); + if ( nFails ) + printf( "Verification failed at %d nodes.\n", nFails ); + else if ( fVerbose ) + printf( "Verification succeeded for all (%d) nodes.\n", Gia_ManCandNum(p) ); +} +void Cec4_ManConvertToLits( Gia_Man_t * p, Vec_Int_t * vRes ) +{ + Gia_Obj_t * pObj; int i, iRepr; + Gia_ManSetPhase( p ); + Gia_ManForEachObj( p, pObj, i ) + if ( (iRepr = Vec_IntEntry(vRes, i)) >= 0 ) + Vec_IntWriteEntry( vRes, i, Abc_Var2Lit(iRepr, Gia_ManObj(p, iRepr)->fPhase ^ pObj->fPhase) ); +} +void Cec4_ManSimulateTest5( Gia_Man_t * p, int nConfs, int fVerbose ) +{ + Vec_Int_t * vRes = NULL; + Gia_Man_t * pAig = Gia_ManLocalRehash( p ); + Cec4_ManSimulateTest5Int( pAig, nConfs, fVerbose ); + vRes = Cec4_ManComputeMapping( p, pAig, fVerbose ); + Cec4_ManVerifyEquivs( p, vRes, fVerbose ); + Cec4_ManConvertToLits( p, vRes ); + Vec_IntDumpBin( "_temp_.equiv", vRes, fVerbose ); + Vec_IntFree( vRes ); + Gia_ManStop( pAig ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// From c23cd0a7c5f4264b3209f127885b8d5432f2fd5a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 27 Jun 2022 09:53:17 -0700 Subject: [PATCH 74/74] Commenting out unimportant assertion. --- src/aig/aig/aigDup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aig/aig/aigDup.c b/src/aig/aig/aigDup.c index 3ccd8dabc..234192cb8 100644 --- a/src/aig/aig/aigDup.c +++ b/src/aig/aig/aigDup.c @@ -1154,7 +1154,7 @@ Aig_Man_t * Aig_ManDupOneOutput( Aig_Man_t * p, int iPoNum, int fAddRegs ) Aig_Man_t * pNew; Aig_Obj_t * pObj = NULL; int i; - assert( Aig_ManRegNum(p) > 0 ); + //assert( Aig_ManRegNum(p) > 0 ); assert( iPoNum < Aig_ManCoNum(p)-Aig_ManRegNum(p) ); // create the new manager pNew = Aig_ManStart( Aig_ManObjNumMax(p) );