diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 2b4a0199f..ed0e682f4 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -6163,6 +6163,62 @@ Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ) Gia_ManStop( pTemp ); return pNew; } +Gia_Man_t * Gia_ManDupUnCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ) +{ + Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; + Vec_Int_t * vOutLits, * vVarLits, * vTemp; + int i, v, g, nVars = Vec_IntSize(vVarNums); + int nMints = 1 << nVars; + int nOrigCos; + assert( Gia_ManRegNum(p) == 0 ); + assert( nMints > 0 ); + assert( Gia_ManCoNum(p) % nMints == 0 ); + nOrigCos = Gia_ManCoNum(p) / nMints; + vVarLits = Vec_IntStartFull( nVars ); + pNew = Gia_ManStart( Gia_ManObjNum(p) + Gia_ManCoNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + { + pObj->Value = Gia_ManAppendCi( pNew ); + if ( (v = Vec_IntFind( vVarNums, i )) >= 0 ) + Vec_IntWriteEntry( vVarLits, v, pObj->Value ); + } + Vec_IntForEachEntry( vVarLits, g, i ) + assert( g >= 0 ); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + vOutLits = Vec_IntAlloc( Gia_ManCoNum(p) ); + Gia_ManForEachCo( p, pObj, i ) + Vec_IntPush( vOutLits, Gia_ObjFanin0Copy(pObj) ); + vTemp = Vec_IntAlloc( nMints ); + for ( i = 0; i < nOrigCos; i++ ) + { + Vec_IntFill( vTemp, nMints, 0 ); + for ( g = 0; g < nMints; g++ ) + Vec_IntWriteEntry( vTemp, g, Vec_IntEntry(vOutLits, g * nOrigCos + i) ); + for ( v = 0; v < nVars; v++ ) + { + int Stride = 1 << v; + for ( g = 0; g < nMints; g += 2 * Stride ) + { + int iLit0 = Vec_IntEntry( vTemp, g ); + int iLit1 = Vec_IntEntry( vTemp, g + Stride ); + int iLitR = Gia_ManHashMux( pNew, Vec_IntEntry( vVarLits, v ), iLit1, iLit0 ); + Vec_IntWriteEntry( vTemp, g, iLitR ); + } + } + Gia_ManAppendCo( pNew, Vec_IntEntry( vTemp, 0 ) ); + } + Vec_IntFree( vTemp ); + Vec_IntFree( vOutLits ); + Vec_IntFree( vVarLits ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} /**Function************************************************************* @@ -6673,4 +6729,3 @@ Gia_Man_t * Gia_ManDupExtractMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * ABC_NAMESPACE_IMPL_END - diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 33323687f..24994dbab 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -36623,10 +36623,11 @@ usage: int Abc_CommandAbc9Cofs( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ); + extern Gia_Man_t * Gia_ManDupUnCofs( Gia_Man_t * p, Vec_Int_t * vVarNums ); Gia_Man_t * pTemp; Vec_Int_t * vVars = NULL; - int c, iVar = 0, nVars = 0, fVerbose = 0; + int c, iVar = 0, nVars = 0, fLastVars = 0, fVerbose = 0, fUndo = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "VNvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "VNluvh" ) ) != EOF ) { switch ( c ) { @@ -36652,6 +36653,12 @@ int Abc_CommandAbc9Cofs( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nVars < 0 ) goto usage; break; + case 'l': + fLastVars ^= 1; + break; + case 'u': + fUndo ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -36672,8 +36679,14 @@ int Abc_CommandAbc9Cofs( Abc_Frame_t * pAbc, int argc, char ** argv ) Vec_IntPush( vVars, iVar ); } else if ( nVars ) { - Abc_Print( 0, "Cofactoring the first %d inputs.\n", nVars ); - vVars = Vec_IntStartNatural( nVars ); + Abc_Print( 0, "Cofactoring the %s %d inputs.\n", fLastVars ? "last":"first", nVars ); + if ( fLastVars) { + vVars = Vec_IntAlloc(nVars); + for ( int v = 0; v < nVars; v++ ) + Vec_IntPush( vVars, Gia_ManCiNum(pAbc->pGia)-nVars+v ); + } + else + vVars = Vec_IntStartNatural( nVars ); } else if ( globalUtilOptind < argc ) { vVars = Vec_IntAlloc( argc ); @@ -36684,16 +36697,18 @@ int Abc_CommandAbc9Cofs( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "One of the parameters, -V or -L , should be set on the command line.\n" ); goto usage; } - pTemp = Gia_ManDupCofs( pAbc->pGia, vVars ); + pTemp = fUndo ? Gia_ManDupUnCofs( pAbc->pGia, vVars ) : Gia_ManDupCofs( pAbc->pGia, vVars ); Abc_FrameUpdateGia( pAbc, pTemp ); Vec_IntFree( vVars ); return 0; usage: - Abc_Print( -2, "usage: &cofs [-VN num] [-vh]\n" ); - Abc_Print( -2, "\t derives cofactors w.r.t the set of variables\n" ); + Abc_Print( -2, "usage: &cofs [-VN num] [-luvh]\n" ); + Abc_Print( -2, "\t derives cofactors or reconstructs them w.r.t the set of variables\n" ); Abc_Print( -2, "\t-V num : the zero-based ID of one variable to cofactor [default = %d]\n", iVar ); Abc_Print( -2, "\t-N num : cofactoring the given number of first input variables [default = %d]\n", nVars ); + Abc_Print( -2, "\t-l : toggle cofactoring last variables instead [default = %s]\n", fLastVars? "yes": "no" ); + Abc_Print( -2, "\t-u : undo cofactoring (recombine cofactors using muxes) [default = %s]\n", fUndo? "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;