Commit 7efe9f2a by Alan Mishchenko

New technology mapper.

parent 634dd6d0
......@@ -584,6 +584,12 @@ int Gia_ManFromIfLogicCreateLut( Gia_Man_t * pNew, word * pRes, Vec_Int_t * vLea
{
int i, iLit, iObjLit1;
iObjLit1 = Kit_TruthToGia( pNew, (unsigned *)pRes, Vec_IntSize(vLeaves), vCover, vLeaves, 0 );
// do not create LUT in the simple case
if ( Abc_Lit2Var(iObjLit1) == 0 )
return iObjLit1;
Vec_IntForEachEntry( vLeaves, iLit, i )
if ( Abc_Lit2Var(iObjLit1) == Abc_Lit2Var(iLit) )
return iObjLit1;
// write mapping
Vec_IntSetEntry( vMapping, Abc_Lit2Var(iObjLit1), Vec_IntSize(vMapping2) );
Vec_IntPush( vMapping2, Vec_IntSize(vLeaves) );
......
......@@ -29518,15 +29518,30 @@ int Abc_CommandAbc9If2( Abc_Frame_t * pAbc, int argc, char ** argv )
char Buffer[200];
Gia_Man_t * pNew;
Mpm_Par_t Pars, * pPars = &Pars;
int c;
int c, nLutSize = 6;
// set defaults
Mpm_ManSetParsDefault( pPars );
// pPars->pLutLib = (If_LibLut_t *)pAbc->pLibLut;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Dvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "KDmzvh" ) ) != 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;
}
globalUtilOptind++;
nLutSize = atoi(argv[globalUtilOptind]);
if ( nLutSize < 2 || nLutSize > 16 )
{
Abc_Print( -1, "LUT size %d is not supported.\n", nLutSize );
goto usage;
}
assert( pPars->pLib == NULL );
pPars->pLib = Mpm_LibLutSetSimple( nLutSize );
break;
case 'D':
if ( globalUtilOptind >= argc )
{
......@@ -29538,6 +29553,12 @@ int Abc_CommandAbc9If2( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->DelayTarget <= 0.0 )
goto usage;
break;
case 'm':
pPars->fCutMin ^= 1;
break;
case 'z':
pPars->fDeriveLuts ^= 1;
break;
case 'v':
pPars->fVerbose ^= 1;
break;
......@@ -29546,8 +29567,13 @@ int Abc_CommandAbc9If2( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage;
}
}
if ( pPars->pLib == NULL )
pPars->pLib = Mpm_LibLutSetSimple( nLutSize );
if ( pPars->fCutMin )
pPars->fUseTruth = 1;
// perform mapping
pNew = Mpm_ManMappingTest( pAbc->pGia, pPars );
Mpm_LibLutFree( pPars->pLib );
if ( pNew == NULL )
{
Abc_Print( -1, "Abc_CommandAbc9If2(): Mapping of GIA has failed.\n" );
......@@ -29561,9 +29587,12 @@ usage:
sprintf(Buffer, "best possible" );
else
sprintf(Buffer, "%d", pPars->DelayTarget );
Abc_Print( -2, "usage: &if2 [-D num] [-vh]\n" );
Abc_Print( -2, "usage: &if2 [-KD num] [-mzvh]\n" );
Abc_Print( -2, "\t performs technology mapping of the network\n" );
Abc_Print( -2, "\t-K num : sets the LUT size for the mapping [default = %s]\n", nLutSize );
Abc_Print( -2, "\t-D num : sets the delay constraint for the mapping [default = %s]\n", Buffer );
Abc_Print( -2, "\t-m : enables cut minimization by removing vacuous variables [default = %s]\n", pPars->fCutMin? "yes": "no" );
Abc_Print( -2, "\t-z : toggles deriving LUTs when mapping into LUT structures [default = %s]\n", pPars->fDeriveLuts? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : prints the command usage\n");
return 1;
......@@ -56,7 +56,12 @@ struct Mpm_LibLut_t_
typedef struct Mpm_Par_t_ Mpm_Par_t;
struct Mpm_Par_t_
{
Mpm_LibLut_t * pLib;
int nNumCuts;
int DelayTarget;
int fUseTruth;
int fCutMin;
int fDeriveLuts;
int fVerbose;
};
......@@ -71,6 +76,9 @@ struct Mpm_Par_t_
/*=== mpmCore.c ===========================================================*/
extern void Mpm_ManSetParsDefault( Mpm_Par_t * p );
/*=== mpmLib.c ===========================================================*/
extern Mpm_LibLut_t * Mpm_LibLutSetSimple( int nLutSize );
extern void Mpm_LibLutFree( Mpm_LibLut_t * pLib );
ABC_NAMESPACE_HEADER_END
......
......@@ -20,6 +20,7 @@
#include "aig/gia/gia.h"
#include "mpmInt.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
......@@ -182,16 +183,29 @@ void * Mpm_ManFromIfLogic( Mpm_Man_t * pMan )
pCutBest = Mpm_ObjCutBestP( pMan, pObj );
Mpm_CutForEachLeaf( pMan->pMig, pCutBest, pFanin, k )
Vec_IntPush( vLeaves, Mig_ObjCopy(pFanin) );
// perform one of the two types of mapping: with and without structures
iLitNew = Mpm_ManNodeIfToGia( pNew, pMan, pObj, vLeaves, 0 );
// write mapping
Vec_IntSetEntry( vMapping, Abc_Lit2Var(iLitNew), Vec_IntSize(vMapping2) );
Vec_IntPush( vMapping2, Vec_IntSize(vLeaves) );
Vec_IntForEachEntry( vLeaves, Entry, k )
assert( Abc_Lit2Var(Entry) < Abc_Lit2Var(iLitNew) );
Vec_IntForEachEntry( vLeaves, Entry, k )
Vec_IntPush( vMapping2, Abc_Lit2Var(Entry) );
Vec_IntPush( vMapping2, Abc_Lit2Var(iLitNew) );
if ( pMan->pPars->fDeriveLuts && pMan->pPars->fUseTruth )
{
extern int Gia_ManFromIfLogicNode( Gia_Man_t * pNew, int iObj, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp,
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking );
word * pTruth = Mpm_CutTruth(pMan, Abc_Lit2Var(pCutBest->iFunc));
// Kit_DsdPrintFromTruth( pTruth, Vec_IntSize(vLeaves) ); printf( "\n" );
// perform decomposition of the cut
iLitNew = Gia_ManFromIfLogicNode( pNew, Mig_ObjId(pObj), vLeaves, vLeaves2, pTruth, NULL, vCover, vMapping, vMapping2, vPacking );
iLitNew = Abc_LitNotCond( iLitNew, pCutBest->fCompl ^ Abc_LitIsCompl(pCutBest->iFunc) );
}
else
{
// perform one of the two types of mapping: with and without structures
iLitNew = Mpm_ManNodeIfToGia( pNew, pMan, pObj, vLeaves, 0 );
// write mapping
Vec_IntSetEntry( vMapping, Abc_Lit2Var(iLitNew), Vec_IntSize(vMapping2) );
Vec_IntPush( vMapping2, Vec_IntSize(vLeaves) );
Vec_IntForEachEntry( vLeaves, Entry, k )
assert( Abc_Lit2Var(Entry) < Abc_Lit2Var(iLitNew) );
Vec_IntForEachEntry( vLeaves, Entry, k )
Vec_IntPush( vMapping2, Abc_Lit2Var(Entry) );
Vec_IntPush( vMapping2, Abc_Lit2Var(iLitNew) );
}
}
else if ( Mig_ObjIsCi(pObj) )
iLitNew = Gia_ManAppendCi(pNew);
......
......@@ -46,8 +46,13 @@ ABC_NAMESPACE_IMPL_START
void Mpm_ManSetParsDefault( Mpm_Par_t * p )
{
memset( p, 0, sizeof(Mpm_Par_t) );
p->DelayTarget = -1; // delay target
p->fVerbose = 0; // verbose output
p->pLib = NULL; // LUT library
p->nNumCuts = 8; // cut number
p->fUseTruth = 0; // uses truth tables
p->fCutMin = 0; // enables cut minimization
p->DelayTarget = -1; // delay target
p->fDeriveLuts = 0; // use truth tables to derive AIG structure
p->fVerbose = 0; // verbose output
}
/**Function*************************************************************
......@@ -61,20 +66,17 @@ void Mpm_ManSetParsDefault( Mpm_Par_t * p )
SeeAlso []
***********************************************************************/
Gia_Man_t * Mpm_ManPerformTest( Mig_Man_t * pMig )
Gia_Man_t * Mpm_ManPerformTest( Mig_Man_t * pMig, Mpm_Par_t * pPars )
{
Gia_Man_t * pNew;
Mpm_LibLut_t * pLib;
Mpm_Man_t * p;
pLib = Mpm_LibLutSetSimple( 6 );
p = Mpm_ManStart( pMig, pLib, 8 );
p = Mpm_ManStart( pMig, pPars );
Mpm_ManPrintStatsInit( p );
Mpm_ManPrepare( p );
Mpm_ManPerform( p );
Mpm_ManPrintStats( p );
pNew = (Gia_Man_t *)Mpm_ManFromIfLogic( p );
Mpm_ManStop( p );
Mpm_LibLutFree( pLib );
return pNew;
}
Gia_Man_t * Mpm_ManMappingTest( Gia_Man_t * pGia, Mpm_Par_t * pPars )
......@@ -82,7 +84,7 @@ Gia_Man_t * Mpm_ManMappingTest( Gia_Man_t * pGia, Mpm_Par_t * pPars )
Mig_Man_t * p;
Gia_Man_t * pNew;
p = Mig_ManCreate( pGia );
pNew = Mpm_ManPerformTest( p );
pNew = Mpm_ManPerformTest( p, pPars );
Mig_ManStop( p );
return pNew;
}
......
......@@ -33,6 +33,7 @@
//#include "misc/tim/tim.h"
#include "misc/vec/vec.h"
#include "misc/vec/vecMem.h"
#include "misc/mem/mem2.h"
#include "mpmMig.h"
#include "mpm.h"
......@@ -58,30 +59,23 @@ typedef struct Mpm_Cut_t_ Mpm_Cut_t; // 8 bytes + NLeaves * 4 bytes
struct Mpm_Cut_t_
{
int hNext; // next cut
unsigned iFunc : 26; // function
unsigned iFunc : 25; // function
unsigned fCompl : 1;
unsigned fUseless : 1; // internal flag
unsigned nLeaves : 5; // leaves
int pLeaves[0]; // leaves
};
typedef struct Mpm_Inf_t_ Mpm_Inf_t; // 32 bytes
struct Mpm_Inf_t_
{
int hCut; // cut handle
unsigned nLeaves : 6; // the number of leaves
unsigned mCost : 26; // area cost of this cut
typedef struct Mpm_Uni_t_ Mpm_Uni_t; // 48 bytes
struct Mpm_Uni_t_
{
int mTime; // arrival time
int mArea; // area (flow)
int mEdge; // edge (flow)
int mAveRefs; // area references
word uSign; // cut signature
};
typedef struct Mpm_Uni_t_ Mpm_Uni_t; // 48 bytes
struct Mpm_Uni_t_
{
Mpm_Inf_t Inf; // information
unsigned iFunc : 26; // function
int Cost; // user cost
unsigned iFunc : 25; // function
unsigned fCompl : 1;
unsigned fUseless : 1; // internal flag
unsigned nLeaves : 5; // leaves
int pLeaves[MPM_VAR_MAX]; // leaves
......@@ -91,9 +85,11 @@ typedef struct Mpm_Man_t_ Mpm_Man_t;
struct Mpm_Man_t_
{
Mig_Man_t * pMig; // AIG manager
Mpm_Par_t * pPars; // mapping parameters
// mapping parameters
int nLutSize; // LUT size
int nNumCuts; // cut count
int nTruWords; // words in the truth table
Mpm_LibLut_t * pLibLut; // LUT library
// mapping attributes
int GloRequired; // global arrival time
......@@ -110,10 +106,13 @@ struct Mpm_Man_t_
Vec_Ptr_t * vTemp; // storage for cuts
// object presence
unsigned char * pObjPres; // object presence
int pObjPresUsed[MPM_VAR_MAX];
int nObjPresUsed;
Mpm_Cut_t * pCutTemp; // temporary cut
Vec_Str_t vObjShared; // object presence
// cut comparison
int (* pCutCmp) (Mpm_Inf_t *, Mpm_Inf_t *);// procedure to compare cuts
int (* pCutCmp) (Mpm_Uni_t *, Mpm_Uni_t *);// procedure to compare cuts
// fanin cuts/signatures
int nCuts[3]; // fanin cut counts
Mpm_Cut_t * pCuts[3][MPM_CUT_MAX+1]; // fanin cuts
......@@ -122,6 +121,10 @@ struct Mpm_Man_t_
// Dsd_Man_t * pManDsd;
void * pManDsd;
int pPerm[MPM_VAR_MAX];
Vec_Mem_t * vTtMem; // truth table memory and hash table
int funcCst0; // constant 0
int funcVar0; // variable 0
unsigned uPermMask[3];
// mapping attributes
Vec_Int_t vCutBests; // cut best
Vec_Int_t vCutLists; // cut list
......@@ -134,6 +137,7 @@ struct Mpm_Man_t_
Vec_Int_t vEdges; // edge
// statistics
int nCutsMerged;
int nSmallSupp;
abctime timeFanin;
abctime timeDerive;
abctime timeMerge;
......@@ -151,7 +155,7 @@ struct Mpm_Man_t_
static inline int Mpm_ObjCutBest( Mpm_Man_t * p, Mig_Obj_t * pObj ) { return Vec_IntEntry(&p->vCutBests, Mig_ObjId(pObj)); }
static inline void Mpm_ObjSetCutBest( Mpm_Man_t * p, Mig_Obj_t * pObj, int i ) { Vec_IntWriteEntry(&p->vCutBests, Mig_ObjId(pObj), i); }
static inline int Mpm_CutWordNum( int nLeaves ) { return (sizeof(Mpm_Cut_t)/sizeof(int) + nLeaves + 1) >> 1; }
static inline int Mpm_CutWordNum( int nLeaves ) { return ((sizeof(Mpm_Cut_t)/sizeof(int) + nLeaves + 1) >> 1); }
static inline Mpm_Cut_t * Mpm_CutFetch( Mpm_Man_t * p, int h ) { Mpm_Cut_t * pCut = (Mpm_Cut_t *)Mmr_StepEntry( p->pManCuts, h ); assert( Mpm_CutWordNum(pCut->nLeaves) == (h & p->pManCuts->uMask) ); return pCut; }
static inline Mpm_Cut_t * Mpm_ObjCutBestP( Mpm_Man_t * p, Mig_Obj_t * pObj ) { return Mpm_CutFetch( p, Mpm_ObjCutBest(p, pObj) ); }
......@@ -159,6 +163,9 @@ static inline int Mpm_ObjCutList( Mpm_Man_t * p, Mig_Obj_t * pObj )
static inline int * Mpm_ObjCutListP( Mpm_Man_t * p, Mig_Obj_t * pObj ) { return Vec_IntEntryP(&p->vCutLists, Mig_ObjId(pObj)); }
static inline void Mpm_ObjSetCutList( Mpm_Man_t * p, Mig_Obj_t * pObj, int i ) { Vec_IntWriteEntry(&p->vCutLists, Mig_ObjId(pObj), i); }
static inline int Mpm_CutLeafNum( Mpm_Cut_t * pCut ) { return pCut->nLeaves; }
static inline word * Mpm_CutTruth( Mpm_Man_t * p, int iFunc ) { return Vec_MemReadEntry(p->vTtMem, iFunc); }
static inline void Mpm_ManSetMigRefs( Mpm_Man_t * p ) { assert( Vec_IntSize(&p->vMigRefs) == Vec_IntSize(&p->pMig->vRefs) ); memcpy( Vec_IntArray(&p->vMigRefs), Vec_IntArray(&p->pMig->vRefs), sizeof(int) * Mig_ManObjNum(p->pMig) ); }
static inline int Mig_ObjMigRefNum( Mpm_Man_t * p, Mig_Obj_t * pObj ) { return Vec_IntEntry(&p->vMigRefs, Mig_ObjId(pObj)); }
static inline int Mig_ObjMigRefDec( Mpm_Man_t * p, Mig_Obj_t * pObj ) { return Vec_IntAddToEntry(&p->vMigRefs, Mig_ObjId(pObj), -1); }
......@@ -183,6 +190,9 @@ static inline void Mpm_ObjSetArea( Mpm_Man_t * p, Mig_Obj_t * pObj, int i
static inline int Mpm_ObjEdge( Mpm_Man_t * p, Mig_Obj_t * pObj ) { return Vec_IntEntry(&p->vEdges, Mig_ObjId(pObj)); }
static inline void Mpm_ObjSetEdge( Mpm_Man_t * p, Mig_Obj_t * pObj, int i ) { Vec_IntWriteEntry(&p->vEdges, Mig_ObjId(pObj), i); }
static inline void Mpm_VarsClear( int * V2P, int * P2V, int nVars ) { int i; for ( i = 0; i < nVars; i++ ) V2P[i] = P2V[i] = i; }
static inline void Mpm_VarsSwap( int * V2P, int * P2V, int iVar, int jVar ) { V2P[P2V[iVar]] = jVar; V2P[P2V[jVar]] = iVar; P2V[iVar] ^= P2V[jVar]; P2V[jVar] ^= P2V[iVar]; P2V[iVar] ^= P2V[jVar]; }
// iterators over object cuts
#define Mpm_ObjForEachCut( p, pObj, hCut, pCut ) \
for ( hCut = Mpm_ObjCutList(p, pObj); hCut && (pCut = Mpm_CutFetch(p, hCut)); hCut = pCut->hNext )
......@@ -203,7 +213,7 @@ static inline void Mpm_ObjSetEdge( Mpm_Man_t * p, Mig_Obj_t * pObj, int i
extern Mig_Man_t * Mig_ManCreate( void * pGia );
extern void * Mpm_ManFromIfLogic( Mpm_Man_t * pMan );
/*=== mpmCore.c ===========================================================*/
extern Mpm_Man_t * Mpm_ManStart( Mig_Man_t * pMig, Mpm_LibLut_t * pLib, int nNumCuts );
extern Mpm_Man_t * Mpm_ManStart( Mig_Man_t * pMig, Mpm_Par_t * pPars );
extern void Mpm_ManStop( Mpm_Man_t * p );
extern void Mpm_ManPrintStatsInit( Mpm_Man_t * p );
extern void Mpm_ManPrintStats( Mpm_Man_t * p );
......@@ -214,6 +224,9 @@ extern void Mpm_LibLutFree( Mpm_LibLut_t * pLib );
/*=== mpmMap.c ===========================================================*/
extern void Mpm_ManPrepare( Mpm_Man_t * p );
extern void Mpm_ManPerform( Mpm_Man_t * p );
/*=== mpmTruth.c ===========================================================*/
extern int Mpm_CutComputeTruth6( Mpm_Man_t * p, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, Mpm_Cut_t * pCut1, Mpm_Cut_t * pCutC, int fCompl0, int fCompl1, int fComplC, int Type );
ABC_NAMESPACE_HEADER_END
......
......@@ -140,6 +140,7 @@ static inline int Mig_ObjIsAnd( Mig_Obj_t * p ) {
static inline int Mig_ObjIsXor( Mig_Obj_t * p ) { return Mig_ObjIsNode2( p ) && Mig_FanId(p, 0) > Mig_FanId(p, 1); }
static inline int Mig_ObjIsMux( Mig_Obj_t * p ) { return Mig_ObjIsNode3( p ); }
static inline int Mig_ObjIsCand( Mig_Obj_t * p ) { return Mig_ObjIsNode(p) || Mig_ObjIsCi(p); }
static inline int Mig_ObjNodeType( Mig_Obj_t * p ) { return Mig_ObjIsAnd(p) ? 1 : (Mig_ObjIsXor(p) ? 2 : 3); }
static inline int Mig_ObjId( Mig_Obj_t * p ) { return Mig_FanId( p, 3 ); }
static inline void Mig_ObjSetId( Mig_Obj_t * p, int v ) { Mig_FanSetId( p, 3, v ); }
......
......@@ -19,6 +19,7 @@
***********************************************************************/
#include "mpmInt.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
......@@ -33,7 +34,7 @@ ABC_NAMESPACE_IMPL_START
/**Function*************************************************************
Synopsis []
Synopsis [Performs truth table computation.]
Description []
......@@ -42,6 +43,101 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
static inline int Mpm_CutTruthMinimize6( Mpm_Man_t * p, Mpm_Cut_t * pCut )
{
unsigned uSupport;
int i, k, nSuppSize;
word t = *Mpm_CutTruth( p, Abc_Lit2Var(pCut->iFunc) );
// compute the support of the cut's function
uSupport = Abc_Tt6SupportAndSize( t, Mpm_CutLeafNum(pCut), &nSuppSize );
if ( nSuppSize == Mpm_CutLeafNum(pCut) )
return 0;
if ( nSuppSize < 2 )
p->nSmallSupp++;
// update leaves and signature
for ( i = k = 0; i < Mpm_CutLeafNum(pCut); i++ )
{
if ( !(uSupport & (1 << i)) )
continue;
if ( k < i )
{
pCut->pLeaves[k] = pCut->pLeaves[i];
Abc_TtSwapVars( &t, p->nLutSize, k, i );
}
k++;
}
assert( k == nSuppSize );
pCut->nLeaves = nSuppSize;
assert( nSuppSize == Abc_TtSupportSize(&t, Mpm_CutLeafNum(pCut)) );
// save the result
if ( t & 1 )
{
t = ~t;
pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, &t ), 1 );
}
else
pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, &t ), 0 );
return 1;
}
static inline word Mpm_TruthStretch6( word Truth, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, int nLimit )
{
int i, k;
for ( i = (int)pCut->nLeaves - 1, k = (int)pCut0->nLeaves - 1; i >= 0 && k >= 0; i-- )
{
if ( pCut0->pLeaves[k] < pCut->pLeaves[i] )
continue;
assert( pCut0->pLeaves[k] == pCut->pLeaves[i] );
if ( k < i )
Abc_TtSwapVars( &Truth, nLimit, k, i );
k--;
}
return Truth;
}
int Mpm_CutComputeTruth6( Mpm_Man_t * p, Mpm_Cut_t * pCut, Mpm_Cut_t * pCut0, Mpm_Cut_t * pCut1, Mpm_Cut_t * pCutC, int fCompl0, int fCompl1, int fComplC, int Type )
{
word * pTruth0 = Mpm_CutTruth( p, Abc_Lit2Var(pCut0->iFunc) );
word * pTruth1 = Mpm_CutTruth( p, Abc_Lit2Var(pCut1->iFunc) );
word * pTruthC = NULL;
word t0 = (fCompl0 ^ pCut0->fCompl ^ Abc_LitIsCompl(pCut0->iFunc)) ? ~*pTruth0 : *pTruth0;
word t1 = (fCompl1 ^ pCut1->fCompl ^ Abc_LitIsCompl(pCut1->iFunc)) ? ~*pTruth1 : *pTruth1;
word tC, t;
t0 = Mpm_TruthStretch6( t0, pCut, pCut0, p->nLutSize );
t1 = Mpm_TruthStretch6( t1, pCut, pCut1, p->nLutSize );
if ( pCutC )
{
pTruthC = Mpm_CutTruth( p, Abc_Lit2Var(pCutC->iFunc) );
tC = (fComplC ^ pCutC->fCompl ^ Abc_LitIsCompl(pCutC->iFunc)) ? ~*pTruthC : *pTruthC;
tC = Mpm_TruthStretch6( tC, pCut, pCutC, p->nLutSize );
}
assert( p->nLutSize <= 6 );
if ( Type == 1 )
t = t0 & t1;
else if ( Type == 2 )
t = t0 ^ t1;
else if ( Type == 3 )
t = (tC & t1) | (~tC & t0);
else assert( 0 );
// save the result
if ( t & 1 )
{
t = ~t;
pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, &t ), 1 );
}
else
pCut->iFunc = Abc_Var2Lit( Vec_MemHashInsert( p->vTtMem, &t ), 0 );
#ifdef MPM_TRY_NEW
{
word tCopy = t;
char pCanonPerm[16];
Abc_TtCanonicize( &tCopy, pCut->nLimit, pCanonPerm );
}
#endif
// if ( p->pPars->fCutMin )
// return Mpm_CutTruthMinimize6( p, pCut );
return 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment