From b10f6bd89929f20c882a4c17c6101e57dd541853 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 27 Nov 2021 17:12:08 -0800 Subject: 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 3f441e99..991f65a4 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; } -- cgit v1.2.3 From f26ea1eaea5b51a3aec8107636c9f88eadfdcee0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 27 Nov 2021 17:37:34 -0800 Subject: 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 cbf4bbb8..9de88980 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 574159c6..5f95bf47 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 ab36874d..22d11219 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 bfdd08ba..e2345617 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 803d5f19..2901096c 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 9e3572f9..32ee7f6e 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 e8cae2ce..3dafa226 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 aae5a732..27da4dc6 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 899901dd..976c59ab 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 ace0807b..116b7c2f 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); -- cgit v1.2.3 From dfa34cc2e4fe408f4ec6046ba9c0834fd2eaafb4 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 30 Nov 2021 15:23:20 -0800 Subject: 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 a7448530..c492b709 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 483f65b9..f6818010 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 ) -- cgit v1.2.3 From 03b9f41786b59f90b1513e9436ec3e1082f80cb3 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Dec 2021 22:20:55 -0800 Subject: 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 b1c5eb82..4722ef0f 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 6e910cd8..c6edb3ab 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] ); -- cgit v1.2.3 From b7176ee3e52c5068d93abd898be0639f9a648230 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 3 Dec 2021 18:48:26 -0800 Subject: 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 29732bc6..70479041 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 e109a9cf..92b47c17 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 89359611..dd954d9a 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]; -- cgit v1.2.3 From 8e72ac36d718cd0dc27f181dfa10746ad4a101ed Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 6 Dec 2021 13:38:09 -0800 Subject: 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 49a90d9c..1164188f 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 ) -- cgit v1.2.3 From fb248e1ca1881e85abda65dafa143436d05035c6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Dec 2021 11:30:06 +0700 Subject: 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 43b46871..6878f78f 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 39f1bebd..b6456ba4 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 748c104c..308f7689 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 00000000..90fc768e --- /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 + -- cgit v1.2.3 From f1b64be84071a431eac9871f8cdc71bc912fd75a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Dec 2021 11:32:53 +0700 Subject: 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 90fc768e..040c74bb 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 ) { -- cgit v1.2.3 From 25b1a0d81c113bca545fd3b2f477e07e1d33e509 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 16 Dec 2021 21:31:09 +0700 Subject: 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 91a9c600..c764a099 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; } -- cgit v1.2.3 From 85b74f68f19fc4857daba703f909a02410f04065 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 17 Dec 2021 10:15:57 +0700 Subject: 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 5548def6..d871905c 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 b3fcd295..da4881cd 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 70479041..1d97f5e4 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 b6456ba4..b1573e73 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 040c74bb..aff88af9 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) ) -- cgit v1.2.3 From f288c4d7f6e97146bdc4de48f14168cbce9d3c96 Mon Sep 17 00:00:00 2001 From: QuantamHD Date: Mon, 20 Dec 2021 12:55:11 -0800 Subject: 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 4b6adab4..49b5c237 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 ); -- cgit v1.2.3 From 491e0e833f9e4037c296a75c88c1aeea00da1e5c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Dec 2021 17:57:41 +0700 Subject: Changes to pattern generation. --- src/aig/gia/giaPat2.c | 95 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 32 deletions(-) diff --git a/src/aig/gia/giaPat2.c b/src/aig/gia/giaPat2.c index f14ce34a..f2cdfe79 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 ) + 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( "%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; + 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 ) { -- cgit v1.2.3 From 41c4d3c09c8a1dd159c477a09482476230b7dbb2 Mon Sep 17 00:00:00 2001 From: Yuri Victorovich Date: Wed, 29 Dec 2021 12:57:23 -0800 Subject: 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 18f2d656..276eddb8 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 844220a0..bf16dcd1 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 -- cgit v1.2.3 From 48498af8189ef321ee876065d8947875cf711294 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 29 Dec 2021 13:08:32 -0800 Subject: 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 18f2d656..276eddb8 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 844220a0..bf16dcd1 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 -- cgit v1.2.3 From 79f04c66534c1a517481a2006dcbbb8e27d1688c Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jan 2022 11:09:10 -0800 Subject: 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 6878f78f..f5e9f5f8 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 da4881cd..55f8901f 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 f2cdfe79..fef4cf5a 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 c3d6e176..cbe2a0f3 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 e860878e..5325adfe 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 b1573e73..d8b8247a 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 308f7689..7277f30b 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 93a1a92a..c658a2fe 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 00000000..a3ac73c0 --- /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 00000000..492005fd --- /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 aff88af9..89680bbd 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) ) -- cgit v1.2.3 From d892e63256063ba04f20ca347121116bc67a30e2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jan 2022 11:13:18 -0800 Subject: 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 492005fd..71b1b98c 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 -- cgit v1.2.3 From 5b8fa41ba966271f97f99860b21eee83bf51e61a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 21 Jan 2022 11:33:53 -0800 Subject: 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 52f9a184..68be112f 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 b0e72284..d1241873 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 1d1dcbe2..c1eceef0 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 42cf11c5..64225c61 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 da0fc846..b2d5c5ee 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 dd858c96..e2be4343 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 ) { -- cgit v1.2.3 From 554a1693ac2bd81169b28227ea718527136f5e7e Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Fri, 21 Jan 2022 22:51:36 +0200 Subject: 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 c706ed8c..00000000 --- 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 00000000..aa97aca2 --- /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 00000000..6312780d --- /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 b9add8c4..00000000 --- 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 bdea392a..3976cf7b 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 be617877..55b9de30 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 1faea72a..6290b88e 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 0bb68a7f..c4b01b50 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 6b1b9e98..3d1fa2fc 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 b3190e39..2eda5038 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); } } -- cgit v1.2.3 From 5fc7e6aac5b5ae42feac13ea347c47281e350516 Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Sat, 22 Jan 2022 22:06:11 +0200 Subject: Build CMake on GitHub Actions --- .github/disabled-workflows/build-posix.yml | 62 ++++++++++++++++++++++++++++ .github/disabled-workflows/build-windows.yml | 48 +++++++++++++++++++++ .github/workflows/build-posix-cmake.yml | 62 ++++++++++++++++++++++++++++ .github/workflows/build-posix.yml | 62 ---------------------------- .github/workflows/build-windows.yml | 48 --------------------- 5 files changed, 172 insertions(+), 110 deletions(-) create mode 100644 .github/disabled-workflows/build-posix.yml create mode 100644 .github/disabled-workflows/build-windows.yml create mode 100644 .github/workflows/build-posix-cmake.yml delete mode 100644 .github/workflows/build-posix.yml delete mode 100644 .github/workflows/build-windows.yml diff --git a/.github/disabled-workflows/build-posix.yml b/.github/disabled-workflows/build-posix.yml new file mode 100644 index 00000000..aa97aca2 --- /dev/null +++ b/.github/disabled-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/disabled-workflows/build-windows.yml b/.github/disabled-workflows/build-windows.yml new file mode 100644 index 00000000..6312780d --- /dev/null +++ b/.github/disabled-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/.github/workflows/build-posix-cmake.yml b/.github/workflows/build-posix-cmake.yml new file mode 100644 index 00000000..86a4d0f9 --- /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/ diff --git a/.github/workflows/build-posix.yml b/.github/workflows/build-posix.yml deleted file mode 100644 index aa97aca2..00000000 --- a/.github/workflows/build-posix.yml +++ /dev/null @@ -1,62 +0,0 @@ -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 deleted file mode 100644 index 6312780d..00000000 --- a/.github/workflows/build-windows.yml +++ /dev/null @@ -1,48 +0,0 @@ -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/ -- cgit v1.2.3 From fd975af1595dbf8f8a703591dac7b5f0059925db Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Sat, 22 Jan 2022 22:07:33 +0200 Subject: 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 86a4d0f9..68d325b2 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 -- cgit v1.2.3 From 2ccb0f783495a65cc597865ba24556cc64b8eaa1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 22 Jan 2022 13:26:06 -0800 Subject: 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 fef4cf5a..dff2c59d 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) ); -- cgit v1.2.3 From 0a536417f6be75fcf26720767a61bd1f57a685b5 Mon Sep 17 00:00:00 2001 From: Baruch Sterin Date: Sun, 23 Jan 2022 00:16:10 +0100 Subject: 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/disabled-workflows/build-posix.yml | 62 ---------------------------- .github/disabled-workflows/build-windows.yml | 48 --------------------- .github/workflows/build-posix-cmake.yml | 6 +-- .github/workflows/build-posix.yml | 62 ++++++++++++++++++++++++++++ .github/workflows/build-windows.yml | 48 +++++++++++++++++++++ CMakeLists.txt | 5 +++ README.md | 5 ++- 7 files changed, 121 insertions(+), 115 deletions(-) delete mode 100644 .github/disabled-workflows/build-posix.yml delete mode 100644 .github/disabled-workflows/build-windows.yml create mode 100644 .github/workflows/build-posix.yml create mode 100644 .github/workflows/build-windows.yml diff --git a/.github/disabled-workflows/build-posix.yml b/.github/disabled-workflows/build-posix.yml deleted file mode 100644 index aa97aca2..00000000 --- a/.github/disabled-workflows/build-posix.yml +++ /dev/null @@ -1,62 +0,0 @@ -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/disabled-workflows/build-windows.yml b/.github/disabled-workflows/build-windows.yml deleted file mode 100644 index 6312780d..00000000 --- a/.github/disabled-workflows/build-windows.yml +++ /dev/null @@ -1,48 +0,0 @@ -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/.github/workflows/build-posix-cmake.yml b/.github/workflows/build-posix-cmake.yml index 68d325b2..ea31fe0b 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/workflows/build-posix.yml b/.github/workflows/build-posix.yml new file mode 100644 index 00000000..aa97aca2 --- /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 00000000..6312780d --- /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/CMakeLists.txt b/CMakeLists.txt index 7cf6f19a..cee9bc72 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 55b9de30..358f5ce9 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 -- cgit v1.2.3 From 6097ac1d1aa67732a98caab517a510731fb2f0b1 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Feb 2022 17:21:30 -0800 Subject: 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 451beed8..0f8b415a 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 ad595ab9..9c23e0d0 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 89a3652f..c73f9918 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 2e819e49..bb957547 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 c975c6ca..cfb388de 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 7a8b265b..4b4c28e7 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); -- cgit v1.2.3 From a6f8625d64e26087b24f9d86b7e7181a05884fda Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Feb 2022 21:37:31 -0800 Subject: 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 a40673a7..ec733b85 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 d8b8247a..2ea17169 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 71b1b98c..b58c2516 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 89680bbd..df53ebe0 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 ) -- cgit v1.2.3 From faa59472783121b7b8c7e4bd4c361a7f5aaf71ab Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 2 Feb 2022 21:39:36 -0800 Subject: 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 b58c2516..62cb70c6 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++ ) { -- cgit v1.2.3 From 6345832dba505bc60f78e5d165ca29d3842cbbd6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 3 Feb 2022 18:45:11 -0800 Subject: 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 e7f6c0ad..eea66f29 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 f8e40b41..63353344 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 b91214af..a560a249 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 5cf74ef9..72fd25bf 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 df53ebe0..97cc9714 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; -- cgit v1.2.3 From ea5648db3f5cc48a2c370be43d8f313db3683967 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 16 Feb 2022 15:32:53 -0800 Subject: 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 a560a249..8250102a 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 1d97f5e4..c92917ac 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 72fd25bf..26bfb1f4 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]; -- cgit v1.2.3 From 33fb7a809d9f076bd3a9e16585f075a96adb42ea Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 16 Feb 2022 21:23:21 -0800 Subject: 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 f5e9f5f8..23c2ce28 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 693cea90..d3ce672f 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 2ea17169..dd7a3e32 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 7277f30b..c1939126 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 00000000..3db27785 --- /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 00000000..abe9a6d8 --- /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 62cb70c6..bc4211ac 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 97cc9714..fa0f0cd5 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 ); -- cgit v1.2.3 From c93c4053d3528efd709a3b5bf78023abd1d183e5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 18 Feb 2022 13:29:38 +1100 Subject: 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 c38369cd..e081e9c6 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 -- cgit v1.2.3 From b442c749e392f4b794556402d8671de869fd81b2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 18 Feb 2022 10:51:49 -0800 Subject: 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 accd9440..bd511fec 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" ); -- cgit v1.2.3 From 31519bd6d6c9cff4691019f72e0faf72e37bde88 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 18 Feb 2022 14:11:17 -0800 Subject: 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 a0042443..fe7286b7 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; -- cgit v1.2.3 From bcf21e46778f63ab4ce490b57648421a2b4d7e28 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 22 Feb 2022 21:14:48 -0800 Subject: 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 eea66f29..b4e22a38 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 d3347a13..8469789b 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 c92917ac..06d7cb08 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 3cc6d793..8ec5944f 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 ef5dd451..87f15238 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 b8934e23..dc1b6036 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 0b0881a6..1da7e4e8 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 52d1fd32..86c5f13e 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 6602702c..e440a652 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; } -- cgit v1.2.3 From 3186a82f65ea8a5847dcf847423cd7f315a3a2ca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 23 Feb 2022 10:11:23 -0800 Subject: 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 8469789b..636fe30a 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 ); } -- cgit v1.2.3 From 6606c18c708deb1844b3bf05d6fa9b5e05003579 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 25 Feb 2022 22:15:13 -0800 Subject: 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 c6edb3ab..cf7ae5df 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 dd7a3e32..37ecf2c7 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" ); -- cgit v1.2.3 From 32693e9857c21c03257ec620fb2439ad36d381e3 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 5 Mar 2022 20:58:38 -0800 Subject: Experiments with word-level data structures. --- src/base/wlc/wlcCom.c | 2 +- src/base/wln/wlnCom.c | 4 +- src/base/wln/wlnGuide.c | 52 +++++++++----- src/base/wln/wlnRead.c | 175 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 194 insertions(+), 39 deletions(-) diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 37ecf2c7..dcddd042 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 3db27785..90ac4faa 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 abe9a6d8..b7e656eb 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 ); + 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 ) + { + 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 ( fscanf( pFile, "%s", pBuffer ) == 1 ) + while ( fgets( pBuffer, 10000, pFile ) ) { - 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) ); + 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 bc4211ac..b4e5f009 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 ); } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From d86e8d9ed858d2ab081fe1ca5bfacdfb7aa28018 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 6 Mar 2022 00:09:35 -0800 Subject: 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 b4e5f009..b42a4791 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 7c101570..40aa9799 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 cfa07ff8..f6a1ab52 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************************************************************* -- cgit v1.2.3 From ee228339e5e14b7a3651454814e91b80c3cb4b1e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 6 Mar 2022 00:10:52 -0800 Subject: 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 b42a4791..95d2dd31 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 ); -- cgit v1.2.3 From 4f2cd590bce70fd5b52b5c92819a54d9294571d3 Mon Sep 17 00:00:00 2001 From: Stephen L Arnold Date: Sun, 27 Mar 2022 12:45:13 -0700 Subject: 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 6312780d..21cd1b26 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: -- cgit v1.2.3 From a24b15d03a87b897494330f0c11319abb129372d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 29 Mar 2022 15:31:13 -0700 Subject: 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 3ccfc011..9e6ee21c 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 = ' '; - } - } else { - // UNIX(TM) file support - if (*(pCur-1)!='\\') nLines++; - else { - // rewind to backslash and overwrite with a space - *(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 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 c0a83cfd..c19c07d4 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 = ' '; - } - } else { - // UNIX(TM) file support - if (*(pCur-1)!='\\') nLines++; - else { - // rewind to backslash and overwrite with a space - *(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 if ( *pCur == '.' ) { + nDots++; } - } - else if ( *pCur == '.' ) - nDots++; - } + } + if ( pnDots ) *pnDots = nDots; if ( pnLines ) -- cgit v1.2.3 From 5405003a5e99758988507cfb0f9ae4341c0025ff Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 2 Apr 2022 23:44:57 -0700 Subject: 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 991f65a4..92dbd0c9 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 ); -- cgit v1.2.3 From 7ad8f9548c359f92cd40afcf715a948acc6b6326 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 4 Apr 2022 22:08:53 -0700 Subject: 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 d871905c..488f12cf 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 55f8901f..4f094b48 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 06d7cb08..db0446c9 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 f6818010..677cb7d0 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 90ac4faa..a010c7c2 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 95d2dd31..43003075 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 ); -- cgit v1.2.3 From e5e5e3545ba835d54386adf96419501c3c5d6dda Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 4 Apr 2022 22:12:58 -0700 Subject: 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 db0446c9..34f15cf2 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; } -- cgit v1.2.3 From b79f37ae57c891640240f1b5a39c70d58f75d8ac Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 22 Apr 2022 15:18:49 -0700 Subject: 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 4f094b48..1164e16b 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 c31064fe..c8808532 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 34f15cf2..e54b831d 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 a010c7c2..dcf12229 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 43003075..8cd4af0c 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 /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 8e13245ed06099734d10942715488ff2dc5b3186 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 08:53:57 -0700 Subject: 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 e54b831d..9813fc1e 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 677cb7d0..76c7cf54 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 40aa9799..92a08b3e 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 ce7e0885..8614ab07 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 9bd83964..c8275b7a 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 1036d7b4..b48db953 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: -- cgit v1.2.3 From 1f56f20e1bcd7528b526cf6d48776a606edf61fd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 09:29:52 -0700 Subject: 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 23c2ce28..cf6e46e8 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 00000000..00ab880b --- /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 00000000..4182cd14 --- /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 d801a243..1cb7331c 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 9813fc1e..6f0f7a34 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 00000000..bdfa0f90 --- /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 23595f23..ed3dac11 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 9a8b97eb..c1d77587 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 c0f96fc4..22de92d2 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 4b4c28e7..d345cd0a 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 b1d38d79..004fdc95 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) ); } -- cgit v1.2.3 From cb30ea0516cf85b839794c4755f6071a02e55537 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 09:59:22 -0700 Subject: 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 6f0f7a34..90d85bde 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 ); -- cgit v1.2.3 From 1abd0457abb9f522da48e24996545b155285bac9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 10:25:46 -0700 Subject: 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 90d85bde..3312ad07 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 bdfa0f90..eaad455b 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 c1d77587..99ca112a 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 9299d290..d1c15639 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 ); -- cgit v1.2.3 From ca6dd4ed17916afb92c4da36ae4ffc8e135f2723 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 13:56:19 -0700 Subject: 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 1164e16b..16ca502c 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 3312ad07..46b2215a 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 dcf12229..6b754457 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 8cd4af0c..ed59358f 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 eaad455b..5f22937c 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; } -- cgit v1.2.3 From dd81af8170f46dfbe801fa75c127664201e19552 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 14:37:46 -0700 Subject: 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 16ca502c..9a82aa3c 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; } -- cgit v1.2.3 From 7693ce6a6ce542d7ef317ea4319f4622693ab016 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 19:15:22 -0700 Subject: 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 9a82aa3c..cc501562 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 ) -- cgit v1.2.3 From 9e164ec52d58655354df6176a51e455270df427f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 20:15:15 -0700 Subject: 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 6b754457..31e0bea3 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; -- cgit v1.2.3 From c68fcae4457bddd80cd3d077a39b6e3381bbd37b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 24 Apr 2022 20:57:41 -0700 Subject: 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 31e0bea3..f3adaf08 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 [] -- cgit v1.2.3 From 0fc56e71997b09fef9cc35f2e3423df723e1e9ce Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Apr 2022 10:39:54 -0700 Subject: 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 f3adaf08..0314fff3 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 ed59358f..cd868185 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 ); + } } } } -- cgit v1.2.3 From 5999b5a516a2256bcd30007f0cdaf7971118bd46 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Apr 2022 17:49:39 -0700 Subject: 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 46b2215a..78c4f556 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 cd868185..276683aa 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; } -- cgit v1.2.3 From daa4eaf2af1bab7330a1f8daf607789f84bfe4e2 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 26 Apr 2022 18:54:12 -0700 Subject: 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 dcddd042..e981e0fa 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 ); -- cgit v1.2.3 From f6758079f7b2d9bd95275d2a7f59bdf9c661232e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 27 Apr 2022 20:54:04 -0700 Subject: 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 8614ab07..d1d8958f 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]; -- cgit v1.2.3 From 61f2f3db6f154360930eb16f7d54f97165ef5d05 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 28 Apr 2022 15:41:02 -0700 Subject: 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 6cc528f2..448706bf 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 -- cgit v1.2.3 From 3d19d411b2417752cc3e64cd93cb7649f29e7276 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 18 May 2022 10:41:39 -0700 Subject: 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 448706bf..f0558cc4 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 12061144..2573d35b 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 -- cgit v1.2.3 From 67247b7209967a94d84e20b77f90dbc0ef5de108 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 18 May 2022 10:42:37 -0700 Subject: 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 377299fd..bb6d0a31 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" ); -- cgit v1.2.3 From 21922e3e9f45023612c64753311bc2f53e59e332 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 18 May 2022 10:43:07 -0700 Subject: 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 78c4f556..c46eb2a7 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 3409543f..835e939b 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 276683aa..a27d38d2 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 aa9608c9..3c2ba703 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 ddfc1036..d33c42d6 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; -- cgit v1.2.3 From 4f7bf9100399a3a25d51d4fd8d6b0bf7cd9ed3ed Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 20 May 2022 12:53:12 -0700 Subject: 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 c46eb2a7..7cabe3c6 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 5f22937c..f8e3ad0a 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 /// -- cgit v1.2.3 From 5a3e0a1f15cf4299470c81fdf314f22ea2f37fa7 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 22 May 2022 19:47:13 -0700 Subject: 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 2573d35b..c501d326 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, -- cgit v1.2.3 From 94ab17c39e847a2326138068fadfe52c3675f70b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Jun 2022 07:47:33 -0700 Subject: 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 431be5b7..d8130550 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 26bfb1f4..9b3d288a 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 bb6d0a31..377299fd 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 d9efa55f..bc8ac3f0 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 c15369d2..e4ea6cfe 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 9cddcd13..51af0214 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 /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From aebf1e7b9c531c7907263cb573d8ff2d1a55cebd Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 2 Jun 2022 09:35:06 -0700 Subject: 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 7cabe3c6..a68c5de0 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 835e939b..cf26c0c7 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 /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 617eb759ae67b7fc839322639ab97cc6200e53af Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Jun 2022 18:27:40 -0700 Subject: 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 7b3aa54c..ff542c30 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 c8808532..002f6bc2 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 a68c5de0..71f8cad5 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] ); -- cgit v1.2.3 From 7bda1d4bfb4f927b04e7b1c03b34eaef5dd88ee8 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 5 Jun 2022 18:28:51 -0700 Subject: 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 0314fff3..eb96132b 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; -- cgit v1.2.3 From 3241a595bab1601a26a10d6452dbd205b2c1480f Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 8 Jun 2022 08:50:37 -0700 Subject: 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 84cda931..1341630b 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) ); } -- cgit v1.2.3 From ae0f03f4a953a98540d67bc64846a492c568c70d Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Jun 2022 14:06:23 -0700 Subject: 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 cf6e46e8..33a2df6f 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 00000000..567bf30b --- /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 f95d815d..f9f5b5e6 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 1cb7331c..35fcb4df 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 71f8cad5..0b60baca 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 [] -- cgit v1.2.3 From 8eb651c3d380168aeb752f90f16b37fff6d39142 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 10 Jun 2022 16:55:12 -0700 Subject: 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 567bf30b..3203a699 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 f9f5b5e6..96721d66 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 ) -- cgit v1.2.3 From 8888e8e82e189a599a340e83ac8094bdef1ceb51 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 23 Jun 2022 07:48:10 -0700 Subject: 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 e50d1270..a3efc0b0 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 7d85214b..cd02db67 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 3c2ba703..13fa4108 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 0c9287a1..c03061af 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 2d6889c0..079781e0 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 4027b780..6ecd0eb8 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 c7180e1c..06e880c2 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 71e0b7b3..963ea15b 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 /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 25455d358febbb26040916f9f90b5e2af87e1dc0 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 23 Jun 2022 08:04:34 -0700 Subject: 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 cf26c0c7..2158f8e9 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 ) -- cgit v1.2.3 From 8cf3f54208b5cdda6a164db4a747a2e4bffcd93b Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sat, 25 Jun 2022 19:44:30 -0700 Subject: 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 9d5152fc..823af19e 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 33a2df6f..d536e0e7 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 00000000..d25ae5db --- /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 35fcb4df..171d8be3 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 0b60baca..f1c8cc7f 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 [] -- cgit v1.2.3 From adcc398bc38c91fa4cc8849aca9eb69c6fb61d21 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 26 Jun 2022 19:45:03 -0700 Subject: 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 c501d326..0365b946 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 f1c8cc7f..33a8315c 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 8275702a..fdbb1866 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 963ea15b..49d0a58f 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 ce299c66..2bbc03d2 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 /// //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From c23cd0a7c5f4264b3209f127885b8d5432f2fd5a Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 27 Jun 2022 09:53:17 -0700 Subject: 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 3ccd8dab..234192cb 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) ); -- cgit v1.2.3