Commit e0ad9de7 by Alan Mishchenko

Improvements to delay-optimization in &satlut.

parent d53161a7
......@@ -209,12 +209,14 @@ void Spl_ManWinFindLeavesRoots( Spl_Man_t * p )
iFan = Gia_ObjFaninId0( pObj, iObj );
if ( !Vec_BitEntry(p->vMarksAnd, iFan) )
{
assert( Gia_ObjIsLut2(p->pGia, iFan) || Vec_BitEntry(p->vMarksCIO, iFan) );
Vec_BitWriteEntry(p->vMarksAnd, iFan, 1);
Vec_IntPush( p->vLeaves, iFan );
}
iFan = Gia_ObjFaninId1( pObj, iObj );
if ( !Vec_BitEntry(p->vMarksAnd, iFan) )
{
assert( Gia_ObjIsLut2(p->pGia, iFan) || Vec_BitEntry(p->vMarksCIO, iFan) );
Vec_BitWriteEntry(p->vMarksAnd, iFan, 1);
Vec_IntPush( p->vLeaves, iFan );
}
......@@ -297,6 +299,28 @@ int Spl_ManCountMarkedFanins( Gia_Man_t * p, int iObj, Vec_Bit_t * vMarks )
Count++;
return Count;
}
int Spl_ManFindGoodCand( Spl_Man_t * p )
{
int i, iObj;
int Res = 0, InCount, InCountMax = -1;
// mark leaves
Vec_IntForEachEntry( p->vInputs, iObj, i )
Vec_BitWriteEntry( p->vMarksIn, iObj, 1 );
// find candidate with maximum input overlap
Vec_IntForEachEntry( p->vCands, iObj, i )
{
InCount = Spl_ManCountMarkedFanins( p->pGia, iObj, p->vMarksIn );
if ( InCountMax < InCount )
{
InCountMax = InCount;
Res = iObj;
}
}
// unmark leaves
Vec_IntForEachEntry( p->vInputs, iObj, i )
Vec_BitWriteEntry( p->vMarksIn, iObj, 0 );
return Res;
}
/**Function*************************************************************
......@@ -313,45 +337,58 @@ int Spl_ManFindOne( Spl_Man_t * p )
{
Vec_Int_t * vVec;
int nFanouts, iObj, iFan, i, k;
int Res = 0, InCount, InCountMax = -1;
Vec_IntClear( p->vCands );
Vec_IntClear( p->vInputs );
int Res = 0;
// deref
Gia_ManForEachLut2Vec( p->vNodes, p->pGia, vVec, iObj, i )
Vec_IntForEachEntry( vVec, iFan, k )
Gia_ObjLutRefDecId( p->pGia, iFan );
// consider LUT inputs - get one that has no refs
if ( p->fReverse )
{
Gia_ManForEachLut2VecReverse( p->vNodes, p->pGia, vVec, iObj, i )
Vec_IntForEachEntry( vVec, iFan, k )
if ( !Vec_BitEntry(p->vMarksNo, iFan) && !Vec_BitEntry(p->vMarksCIO, iFan) )
{
if ( !Gia_ObjLutRefNumId(p->pGia, iFan) )
{
Res = iFan;
goto finish;
}
Vec_IntPush( p->vCands, iFan );
Vec_IntPush( p->vInputs, iFan );
}
}
else
// collect external nodes
if ( p->fReverse && (Vec_IntSize(p->vNodes) & 1) )
{
Gia_ManForEachLut2Vec( p->vNodes, p->pGia, vVec, iObj, i )
Vec_IntForEachEntry( vVec, iFan, k )
if ( !Vec_BitEntry(p->vMarksNo, iFan) && !Vec_BitEntry(p->vMarksCIO, iFan) )
{
if ( !Gia_ObjLutRefNumId(p->pGia, iFan) )
{
Res = iFan;
goto finish;
}
Vec_IntPush( p->vCands, iFan );
Vec_IntPush( p->vInputs, iFan );
}
Vec_IntForEachEntry( p->vNodes, iObj, i )
{
if ( Gia_ObjLutRefNumId(p->pGia, iObj) == 0 )
continue;
assert( Gia_ObjLutRefNumId(p->pGia, iObj) > 0 );
if ( Gia_ObjLutRefNumId(p->pGia, iObj) >= 5 ) // skip nodes with high fanout!
continue;
nFanouts = Spl_ManLutFanouts( p->pGia, iObj, p->vFanouts, p->vMarksNo, p->vMarksCIO );
if ( Gia_ObjLutRefNumId(p->pGia, iObj) == 1 && nFanouts == 1 )
{
Res = Vec_IntEntry(p->vFanouts, 0);
goto finish;
}
//Vec_IntAppend( p->vCands, p->vFanouts );
}
}
// consider LUT inputs - get one that has no refs
Vec_IntClear( p->vCands );
Vec_IntClear( p->vInputs );
Gia_ManForEachLut2Vec( p->vNodes, p->pGia, vVec, iObj, i )
Vec_IntForEachEntry( vVec, iFan, k )
if ( !Vec_BitEntry(p->vMarksNo, iFan) && !Vec_BitEntry(p->vMarksCIO, iFan) && !Gia_ObjLutRefNumId(p->pGia, iFan) )
{
Vec_IntPush( p->vCands, iFan );
Vec_IntPush( p->vInputs, iFan );
}
Res = Spl_ManFindGoodCand( p );
if ( Res )
goto finish;
// collect candidates
Vec_IntClear( p->vCands );
Vec_IntClear( p->vInputs );
Gia_ManForEachLut2Vec( p->vNodes, p->pGia, vVec, iObj, i )
Vec_IntForEachEntry( vVec, iFan, k )
if ( !Vec_BitEntry(p->vMarksNo, iFan) && !Vec_BitEntry(p->vMarksCIO, iFan) )
{
Vec_IntPush( p->vCands, iFan );
Vec_IntPush( p->vInputs, iFan );
}
// all inputs have refs - collect external nodes
Vec_IntForEachEntry( p->vNodes, iObj, i )
{
......@@ -369,22 +406,10 @@ int Spl_ManFindOne( Spl_Man_t * p )
Vec_IntAppend( p->vCands, p->vFanouts );
}
// mark leaves
Vec_IntForEachEntry( p->vInputs, iObj, i )
Vec_BitWriteEntry( p->vMarksIn, iObj, 1 );
// find candidate with maximum input overlap
Vec_IntForEachEntry( p->vCands, iObj, i )
{
InCount = Spl_ManCountMarkedFanins( p->pGia, iObj, p->vMarksIn );
if ( InCountMax < InCount )
{
InCountMax = InCount;
Res = iObj;
}
}
// unmark leaves
Vec_IntForEachEntry( p->vInputs, iObj, i )
Vec_BitWriteEntry( p->vMarksIn, iObj, 0 );
// choose among not-so-good ones
Res = Spl_ManFindGoodCand( p );
if ( Res )
goto finish;
// get the first candidate
if ( Res == 0 && Vec_IntSize(p->vCands) > 0 )
......
......@@ -34827,10 +34827,11 @@ usage:
***********************************************************************/
int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern void Gia_ManLutSat( Gia_Man_t * p, int nNumber, int nConfl, int fReverse, int fVerbose );
int c, nNumber = 64, nConfl = 500, fReverse = 0, fVerbose = 0;
extern void Gia_ManLutSat( Gia_Man_t * p, int nNumber, int nBTLimit, int DelayMax, int fDelay, int fReverse, int fVeryVerbose, int fVerbose );
int c, nNumber = 64, nBTLimit = 500, DelayMax = 0;
int fDelay = 0, fReverse = 0, fVeryVerbose = 0, fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "NCrvh" ) ) != EOF )
while ( ( c = Extra_UtilGetopt( argc, argv, "NCDdrwvh" ) ) != EOF )
{
switch ( c )
{
......@@ -34854,12 +34855,27 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Print( -1, "Command line switch \"-C\" should be followed by a positive integer.\n" );
goto usage;
}
nConfl = atoi(argv[globalUtilOptind]);
nBTLimit = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by a positive integer.\n" );
goto usage;
}
DelayMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'd':
fDelay ^= 1;
break;
case 'r':
fReverse ^= 1;
break;
case 'w':
fVeryVerbose ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
......@@ -34880,15 +34896,18 @@ int Abc_CommandAbc9SatLut( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1;
}
if ( Gia_ManLutSizeMax(pAbc->pGia) > 4 )
Abc_Print( 0, "Current AIG has mapping into %d-LUTs.\n", Gia_ManLutSizeMax(pAbc->pGia) );
Gia_ManLutSat( pAbc->pGia, nNumber, nConfl, fReverse, fVerbose );
Abc_Print( 0, "Current AIG is mapped into %d-LUTs (only 4-LUT mapping is currently supported).\n", Gia_ManLutSizeMax(pAbc->pGia) );
else
Gia_ManLutSat( pAbc->pGia, nNumber, nBTLimit, DelayMax, fDelay, fReverse, fVeryVerbose, fVerbose );
return 0;
usage:
Abc_Print( -2, "usage: &satlut [-NC num] [-rvh]\n" );
Abc_Print( -2, "usage: &satlut [-NCD num] [-drwvh]\n" );
Abc_Print( -2, "\t performs SAT-based remapping of the 4-LUT network\n" );
Abc_Print( -2, "\t-N num : the limit on the number of AIG nodes in the window [default = %d]\n", nNumber );
Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nNumber );
Abc_Print( -2, "\t-C num : the limit on the number of conflicts [default = %d]\n", nBTLimit );
Abc_Print( -2, "\t-D num : the user-specified required times at the outputs [default = %d]\n", DelayMax );
Abc_Print( -2, "\t-d : toggles delay optimization [default = %s]\n", fDelay? "yes": "no" );
Abc_Print( -2, "\t-r : toggles using reverse search [default = %s]\n", fReverse? "yes": "no" );
Abc_Print( -2, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : prints the command usage\n");
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