From 36a83acf3cfdd34485dd47d3786f73931c8f3d32 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 31 Mar 2023 19:52:46 +0700 Subject: [PATCH] Experiments with sequential mapping. --- src/aig/gia/gia.h | 2 + src/aig/gia/giaIf.c | 9 +- src/aig/gia/giaSif.c | 519 ++++++++++++++++++++++++++++++++++++----- src/base/abci/abc.c | 14 +- src/base/abci/abcSat.c | 32 +++ 5 files changed, 505 insertions(+), 71 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 18782d3cc..e44617689 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1238,6 +1238,8 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObj) = Gia_ManCo(p, Gia_ManPoNum(p)+i)); i++ ) #define Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) \ for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObjRi) = Gia_ManCo(p, Gia_ManPoNum(p)+i)) && ((pObjRo) = Gia_ManCi(p, Gia_ManPiNum(p)+i)); i++ ) +#define Gia_ManForEachRoToRiVec( vRoIds, p, pObj, i ) \ + for ( i = 0; (i < Vec_IntSize(vRoIds)) && ((pObj) = Gia_ObjRoToRi(p, Gia_ManObj(p, Vec_IntEntry(vRoIds, i)))); i++ ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DECLARATIONS /// diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 8b4e5b123..7c5e706e8 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -558,11 +558,12 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) FILE * pTable = fopen( pDumpFile, "a+" ); if ( strcmp( FileNameOld, p->pName ) ) { - sprintf( FileNameOld, "%s", p->pName ); + sprintf( FileNameOld, "%s_out", p->pName ); fprintf( pTable, "\n" ); fprintf( pTable, "%s ", p->pName ); fprintf( pTable, " " ); - fprintf( pTable, "%d ", Gia_ManAndNum(p) ); + //fprintf( pTable, "%d ", Gia_ManAndNum(p) ); + fprintf( pTable, "%d ", Gia_ManRegNum(p) ); fprintf( pTable, "%d ", nLuts ); fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); @@ -575,11 +576,13 @@ void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile ) //printf( "This part of the code is currently not used.\n" ); //assert( 0 ); fprintf( pTable, " " ); + fprintf( pTable, " " ); + fprintf( pTable, "%d ", Gia_ManRegNum(p) ); fprintf( pTable, "%d ", nLuts ); fprintf( pTable, "%d ", Gia_ManLutLevelWithBoxes(p) ); //fprintf( pTable, "%d ", Gia_ManRegBoxNum(p) ); //fprintf( pTable, "%d ", Gia_ManNonRegBoxNum(p) ); - fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); +// fprintf( pTable, "%.2f", 1.0*(Abc_Clock() - clk)/CLOCKS_PER_SEC ); clk = Abc_Clock(); } fclose( pTable ); diff --git a/src/aig/gia/giaSif.c b/src/aig/gia/giaSif.c index d25ae5db2..e5ba96a39 100644 --- a/src/aig/gia/giaSif.c +++ b/src/aig/gia/giaSif.c @@ -6,7 +6,7 @@ PackageName [Scalable AIG package.] - Synopsis [] + Synopsis [Sequential mapping.] Author [Alan Mishchenko] @@ -19,11 +19,9 @@ ***********************************************************************/ #include "gia.h" -#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START - //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// @@ -43,7 +41,348 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -static inline void Gia_ManCutMerge( int * pCut, int * pCut1, int * pCut2, int nSize ) +void Gia_ManSifDupNode_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjUpdateTravIdCurrent(p, pObj) ) + return; + assert( Gia_ObjIsAnd(pObj) ); + Gia_ManSifDupNode_rec( pNew, p, Gia_ObjFanin0(pObj) ); + Gia_ManSifDupNode_rec( pNew, p, Gia_ObjFanin1(pObj) ); + pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +void Gia_ManSifDupNode( Gia_Man_t * pNew, Gia_Man_t * p, int iObj, Vec_Int_t * vCopy ) +{ + int k, iFan; + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + Gia_ManIncrementTravId( p ); + Gia_LutForEachFanin( p, iObj, iFan, k ) + { + assert( Vec_IntEntry(vCopy, iFan) >= 0 ); + Gia_ManObj(p, iFan)->Value = Vec_IntEntry(vCopy, iFan); + Gia_ObjUpdateTravIdCurrentId(p, iFan); + } + Gia_ManSifDupNode_rec( pNew, p, pObj ); + Vec_IntWriteEntry( vCopy, iObj, pObj->Value ); +} +Vec_Int_t * Gia_ManSifInitNeg( Gia_Man_t * p, Vec_Int_t * vMoves, Vec_Int_t * vRegs ) +{ + Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRegs) ); + Gia_Obj_t * pObj; int i, iObj; + Gia_Man_t * pNew = Gia_ManStart( 1000 ), * pTemp; + Vec_Int_t * vCopy = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntWriteEntry( vCopy, 0, 0 ); + Gia_ManForEachRo( p, pObj, i ) + Vec_IntWriteEntry( vCopy, Gia_ObjId(p, pObj), Gia_ManAppendCi(pNew) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Vec_IntForEachEntry( vMoves, iObj, i ) + Gia_ManSifDupNode( pNew, p, iObj, vCopy ); + Vec_IntForEachEntry( vRegs, iObj, i ) + { + int iLit = Vec_IntEntry( vCopy, iObj ); + assert( iLit >= 0 ); + Gia_ManAppendCo( pNew, iLit ); + } + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + Gia_ManSetPhase( pNew ); + Gia_ManForEachPo( pNew, pObj, i ) + Vec_IntPush( vRes, pObj->fPhase ); + Gia_ManStop( pNew ); + Vec_IntFree( vCopy ); + assert( Vec_IntSize(vRes) == Vec_IntSize(vRegs) ); + return vRes; +} +Vec_Int_t * Gia_ManSifInitPos( Gia_Man_t * p, Vec_Int_t * vMoves, Vec_Int_t * vRegs ) +{ + extern int * Abc_NtkSolveGiaMiter( Gia_Man_t * p ); + int i, iObj, iLitAnd = 1, * pResult = NULL; + Gia_Obj_t * pObj; Vec_Int_t * vRes = NULL; + Gia_Man_t * pNew = Gia_ManStart( 1000 ), * pTemp; + Vec_Int_t * vCopy = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntWriteEntry( vCopy, 0, 0 ); + Vec_IntForEachEntry( vRegs, iObj, i ) + Vec_IntWriteEntry( vCopy, iObj, Gia_ManAppendCi(pNew) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Vec_IntForEachEntry( vMoves, iObj, i ) + Gia_ManSifDupNode( pNew, p, iObj, vCopy ); + Gia_ManForEachRi( p, pObj, i ) + { + int iFan = Gia_ObjFaninId0p(p, pObj); + int iLit = Vec_IntEntry(vCopy, iFan); + if ( iLit == -1 ) + continue; + iLit = Abc_LitNotCond( iLit, Gia_ObjFaninC0(pObj) ); + iLitAnd = Gia_ManAppendAnd2( pNew, iLitAnd, Abc_LitNot(iLit) ); + } + Gia_ManAppendCo( pNew, iLitAnd ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + pResult = Abc_NtkSolveGiaMiter( pNew ); + if ( pResult ) + { + vRes = Vec_IntAllocArray( pResult, Vec_IntSize(vRegs) ); + Gia_ManSetPhasePattern( pNew, vRes ); + assert( Gia_ManPo(pNew, 0)->fPhase == 1 ); + } + else + { + vRes = Vec_IntStart( Vec_IntSize(vRegs) ); + printf( "***!!!*** The SAT problem has no solution. Using all-0 initial state. ***!!!***\n" ); + } + Gia_ManStop( pNew ); + Vec_IntFree( vCopy ); + assert( Vec_IntSize(vRes) == Vec_IntSize(vRegs) ); + return vRes; +} +Gia_Man_t * Gia_ManSifDerive( Gia_Man_t * p, Vec_Int_t * vCounts, int fVerbose ) +{ + Gia_Man_t * pNew = NULL; Gia_Obj_t * pObj; + Vec_Int_t * vCopy = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vCopy2 = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_Int_t * vLuts[3], * vRos[3], * vRegs[2], * vInits[2], * vTemp; + int i, k, Id, iFan; + for ( i = 0; i < 3; i++ ) + { + vLuts[i] = Vec_IntAlloc(100); + vRos[i] = Vec_IntAlloc(100); + if ( i == 2 ) break; + vRegs[i] = Vec_IntAlloc(100); + } + Gia_ManForEachLut( p, i ) + if ( Vec_IntEntry(vCounts, i) == 1 ) + Vec_IntPush( vLuts[0], i ); + else if ( Vec_IntEntry(vCounts, i) == -1 ) + Vec_IntPush( vLuts[1], i ); + else if ( Vec_IntEntry(vCounts, i) == 0 ) + Vec_IntPush( vLuts[2], i ); + else assert( 0 ); + assert( Vec_IntSize(vLuts[0]) || Vec_IntSize(vLuts[1]) ); + if ( Vec_IntSize(vLuts[0]) ) + { + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vLuts[0], Id, i ) + Gia_ObjSetTravIdCurrentId(p, Id); + Gia_ManForEachRo( p, pObj, i ) + if ( Gia_ObjIsTravIdCurrent(p, Gia_ObjFanin0(Gia_ObjRoToRi(p, pObj))) ) + Vec_IntPush( vRos[0], Gia_ObjId(p, pObj) ); + assert( !Vec_IntSize(vLuts[0]) == !Vec_IntSize(vRos[0]) ); + } + if ( Vec_IntSize(vLuts[1]) ) + { + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vLuts[1], Id, i ) + Gia_LutForEachFanin( p, Id, iFan, k ) + Gia_ObjSetTravIdCurrentId(p, iFan); + Gia_ManForEachRo( p, pObj, i ) + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + Vec_IntPush( vRos[1], Gia_ObjId(p, pObj) ); + assert( !Vec_IntSize(vLuts[1]) == !Vec_IntSize(vRos[1]) ); + } + Gia_ManIncrementTravId( p ); + for ( k = 0; k < 2; k++ ) + Vec_IntForEachEntry( vRos[k], Id, i ) + Gia_ObjSetTravIdCurrentId(p, Id); + Gia_ManForEachRo( p, pObj, i ) + if ( !Gia_ObjIsTravIdCurrent(p, pObj) ) + Vec_IntPush( vRos[2], Gia_ObjId(p, pObj) ); + + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vLuts[0], Id, i ) + Gia_ObjSetTravIdCurrentId(p, Id); + Vec_IntForEachEntry( vLuts[0], Id, i ) + Gia_LutForEachFanin( p, Id, iFan, k ) + if ( !Gia_ObjUpdateTravIdCurrentId(p, iFan) ) + Vec_IntPush( vRegs[0], iFan ); + Vec_IntSort( vRegs[0], 0 ); + assert( Vec_IntCountDuplicates(vRegs[1]) == 0 ); + assert( !Vec_IntSize(vLuts[0]) == !Vec_IntSize(vRegs[0]) ); + + Gia_ManIncrementTravId( p ); + Vec_IntForEachEntry( vLuts[0], Id, i ) + Gia_LutForEachFanin( p, Id, iFan, k ) + Gia_ObjSetTravIdCurrentId(p, iFan); + Vec_IntForEachEntry( vLuts[2], Id, i ) + Gia_LutForEachFanin( p, Id, iFan, k ) + Gia_ObjSetTravIdCurrentId(p, iFan); + Gia_ManForEachCo( p, pObj, i ) + Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId0p(p, pObj)); + Vec_IntForEachEntry( vRos[1], Id, i ) + if ( Gia_ObjIsTravIdCurrentId(p, Id) ) + Vec_IntPush( vRegs[1], Id ); + Vec_IntForEachEntry( vLuts[1], Id, i ) + if ( Gia_ObjIsTravIdCurrentId(p, Id) ) + Vec_IntPush( vRegs[1], Id ); + Vec_IntSort( vRegs[1], 0 ); + assert( Vec_IntCountDuplicates(vRegs[1]) == 0 ); + assert( !Vec_IntSize(vLuts[1]) == !Vec_IntSize(vRegs[1]) ); + + vInits[0] = Vec_IntSize(vLuts[0]) ? Gia_ManSifInitPos( p, vLuts[0], vRegs[0] ) : Vec_IntAlloc(0); + vInits[1] = Vec_IntSize(vLuts[1]) ? Gia_ManSifInitNeg( p, vLuts[1], vRegs[1] ) : Vec_IntAlloc(0); + + if ( fVerbose ) + { + printf( "Flops : %5d %5d %5d\n", Vec_IntSize(vRos[0]), Vec_IntSize(vRos[1]), Vec_IntSize(vRos[2]) ); + printf( "LUTs : %5d %5d %5d\n", Vec_IntSize(vLuts[0]), Vec_IntSize(vLuts[1]), Vec_IntSize(vLuts[2]) ); + printf( "Spots : %5d %5d %5d\n", Vec_IntSize(vRegs[0]), Vec_IntSize(vRegs[1]), 0 ); + } + + pNew = Gia_ManStart( Gia_ManObjNum(p) + Vec_IntSize(vRegs[0]) + Vec_IntSize(vRegs[1]) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + + Vec_IntWriteEntry( vCopy, 0, 0 ); + Gia_ManForEachPi( p, pObj, i ) + Vec_IntWriteEntry( vCopy, Gia_ObjId(p, pObj), Gia_ManAppendCi(pNew) ); + Vec_IntForEachEntry( vRos[2], Id, i ) + Vec_IntWriteEntry( vCopy, Id, Gia_ManAppendCi(pNew) ); + Vec_IntForEachEntry( vRegs[1], Id, i ) + Vec_IntWriteEntry( vCopy, Id, Abc_LitNotCond(Gia_ManAppendCi(pNew), Vec_IntEntry(vInits[1], i)) ); + + vTemp = Vec_IntAlloc(100); + Vec_IntForEachEntry( vRegs[0], Id, i ) + Vec_IntPush( vTemp, Vec_IntEntry(vCopy, Id) ); + Vec_IntForEachEntry( vRegs[0], Id, i ) + Vec_IntWriteEntry( vCopy, Id, Abc_LitNotCond(Gia_ManAppendCi(pNew), Vec_IntEntry(vInits[0], i)) ); + Vec_IntForEachEntry( vLuts[0], Id, i ) + Gia_ManSifDupNode( pNew, p, Id, vCopy ); + Vec_IntForEachEntry( vRegs[0], Id, i ) + Vec_IntWriteEntry( vCopy, Id, Vec_IntEntry(vTemp, i) ); + Vec_IntFree( vTemp ); + + Gia_ManForEachRoToRiVec( vRos[0], p, pObj, i ) + Vec_IntWriteEntry( vCopy, Vec_IntEntry(vRos[0], i), Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) ); + Vec_IntForEachEntry( vLuts[2], Id, i ) + Gia_ManSifDupNode( pNew, p, Id, vCopy ); + + Gia_ManForEachRoToRiVec( vRos[1], p, pObj, i ) + Vec_IntWriteEntry( vCopy2, Vec_IntEntry(vRos[1], i), Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) ); + Vec_IntForEachEntry( vLuts[1], Id, i ) + Gia_ManSifDupNode( pNew, p, Id, vCopy2 ); + + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) ); + Gia_ManForEachRoToRiVec( vRos[2], p, pObj, i ) + Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy, Gia_ObjFaninId0p(p, pObj)), Gia_ObjFaninC0(pObj)) ); + Vec_IntForEachEntry( vRegs[1], Id, i ) + Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy2, Id), Vec_IntEntry(vInits[1], i)) ); + Vec_IntForEachEntry( vRegs[0], Id, i ) + Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vCopy, Id), Vec_IntEntry(vInits[0], i)) ); + + Gia_ManSetRegNum( pNew, Vec_IntSize(vRos[2]) + Vec_IntSize(vRegs[0]) + Vec_IntSize(vRegs[1]) ); + + for ( i = 0; i < 3; i++ ) + { + Vec_IntFreeP( &vLuts[i] ); + Vec_IntFreeP( &vRos[i] ); + if ( i == 2 ) break; + Vec_IntFreeP( &vRegs[i] ); + Vec_IntFreeP( &vInits[i] ); + } + Vec_IntFree( vCopy ); + Vec_IntFree( vCopy2 ); + return pNew; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSifArea_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCuts, int nSize ) +{ + int i, * pCut, Area = 1; + if ( Gia_ObjUpdateTravIdCurrent(p, pObj) ) + return 0; + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + pCut = Vec_IntEntryP( vCuts, Gia_ObjId(p, pObj)*nSize ); + for ( i = 1; i <= pCut[0]; i++ ) + Area += Gia_ManSifArea_rec( p, Gia_ManObj(p, pCut[i] >> 8), vCuts, nSize ); + return Area; +} +int Gia_ManSifArea( Gia_Man_t * p, Vec_Int_t * vCuts, int nSize ) +{ + Gia_Obj_t * pObj; int i, nArea = 0; + Gia_ManIncrementTravId( p ); + Gia_ManForEachCo( p, pObj, i ) + nArea += Gia_ManSifArea_rec( p, Gia_ObjFanin0(pObj), vCuts, nSize ); + return nArea; +} +int Gia_ManSifDelay_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize ) +{ + int i, * pCut, Delay, nFails = 0; + if ( Gia_ObjUpdateTravIdCurrent(p, pObj) ) + return 0; + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + pCut = Vec_IntEntryP( vCuts, Gia_ObjId(p, pObj)*nSize ); + Delay = -ABC_INFINITY-10000; + for ( i = 1; i <= pCut[0]; i++ ) + { + nFails += Gia_ManSifDelay_rec( p, Gia_ManObj(p, pCut[i] >> 8), vCuts, vTimes, nSize ); + Delay = Abc_MaxInt( Delay, Vec_IntEntry(vTimes, pCut[i] >> 8) ); + } + Delay += 1; + return nFails + (int)(Delay > Vec_IntEntry(vTimes, Gia_ObjId(p, pObj))); +} +int Gia_ManSifDelay( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nSize ) +{ + Gia_Obj_t * pObj; int i, nFails = 0; + Gia_ManIncrementTravId( p ); + Gia_ManForEachCo( p, pObj, i ) + nFails += Gia_ManSifDelay_rec( p, Gia_ObjFanin0(pObj), vCuts, vTimes, nSize ); + return nFails; +} +static inline int Gia_ManSifTimeToCount( int Value, int Period ) +{ + return (Period*0xFFFF + Value)/Period + ((Period*0xFFFF + Value)%Period != 0) - 0x10000; +} +Vec_Int_t * Gia_ManSifTimesToCounts( Gia_Man_t * p, Vec_Int_t * vTimes, int Period ) +{ + int i, Times; + Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_IntFillExtra( vTimes, Gia_ManObjNum(p), 0 ); + Vec_IntForEachEntry( vTimes, Times, i ) + if ( Gia_ObjIsLut(p, i) ) + Vec_IntWriteEntry( vCounts, i, Gia_ManSifTimeToCount(Times, Period) ); + return vCounts; +} +Gia_Man_t * Gia_ManSifTransform( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int fVerbose ) +{ + Gia_Man_t * pTemp = NULL, * pNew = NULL; Vec_Int_t * vCounts = NULL, * vTimesNew = NULL; + if ( fVerbose ) + printf( "Current area = %d. Period = %d. ", Gia_ManSifArea(p, vCuts, nLutSize+1), Period ); + if ( fVerbose ) + printf( "Delay checking failed for %d cuts.\n", Gia_ManSifDelay( p, vCuts, vTimes, nLutSize+1 ) ); + vCounts = Gia_ManSifTimesToCounts( p, vTimes, Period ); + pNew = Gia_ManSifDerive( p, vCounts, fVerbose ); + Vec_IntFreeP( &vCounts ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_ManSifCutMerge( int * pCut, int * pCut1, int * pCut2, int nSize ) { int * pBeg = pCut+1; int * pBeg1 = pCut1+1; @@ -85,7 +424,7 @@ static inline void Gia_ManCutMerge( int * pCut, int * pCut1, int * pCut2, int nS 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 ) +static inline int Gia_ManSifCutChoice( 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 ); @@ -97,127 +436,165 @@ static inline int Gia_ManCutChoice( Gia_Man_t * p, int Level, int iObj, int iSib 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 ) +static inline int Gia_ManSifCutOne( 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 Cut0[2] = { 1, iFan0 << 8 }; + int Cut1[2] = { 1, iFan1 << 8 }; 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; + int Level = -ABC_INFINITY, i; + assert( pCut0[0] > 0 && pCut1[0] > 0 ); if ( Level0 == Level1 ) - Gia_ManCutMerge( pCut, pCut0, pCut1, nSize ); + Gia_ManSifCutMerge( pCut, pCut0, pCut1, nSize ); else if ( Level0 > Level1 ) - Gia_ManCutMerge( pCut, pCut0, Cut1, nSize ); + Gia_ManSifCutMerge( pCut, pCut0, Cut1, nSize ); else //if ( Level0 < Level1 ) - Gia_ManCutMerge( pCut, pCut1, Cut0, nSize ); + Gia_ManSifCutMerge( pCut, pCut1, Cut0, nSize ); if ( pCut[0] == -1 ) { pCut[0] = 2; - pCut[1] = iFan0; - pCut[2] = iFan1; - Level++; + pCut[1] = iFan0 << 8; + pCut[2] = iFan1 << 8; } + for ( i = 1; i <= pCut[0]; i++ ) + Level = Abc_MaxInt( Level, Vec_IntEntry(vTimes, pCut[i] >> 8) ); + Level++; if ( Gia_ObjSibl(p, iObj) ) - Level = Gia_ManCutChoice( p, Level, iObj, Gia_ObjSibl(p, iObj), vCuts, vTimes, nSize ); + Level = Gia_ManSifCutChoice( 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 Gia_ManSifCheckIter( 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 ) + fChange |= Gia_ManSifCutOne( p, i, vCuts, vTimes, nSize ); + Gia_ManForEachCo( p, pObj, i ) Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) ); + Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) + { + int TimeNew = Vec_IntEntry(vTimes, Gia_ObjId(p, pObjRi)) - Period; + TimeNew = Abc_MaxInt( TimeNew, Vec_IntEntry(vTimes, Gia_ObjId(p, pObjRo)) ); + Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObjRo), TimeNew ); + } return fChange; } -int Gia_ManCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters ) +int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters ) { - Gia_Obj_t * pObj; int i; + Gia_Obj_t * pObj; int i, Id, nSize = nLutSize+1; assert( Gia_ManRegNum(p) > 0 ); - Vec_IntFill( vTimes, Gia_ManObjNum(p), -ABC_INFINITY ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntWriteEntry( vCuts, Id*nSize, 1 ); + Gia_ManForEachCiId( p, Id, i ) + Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 ); + Vec_IntFill( vTimes, Gia_ManObjNum(p), -Period ); 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) ) + if ( !Gia_ManSifCheckIter(p, vCuts, vTimes, nLutSize, Period) ) return 1; Gia_ManForEachPo( p, pObj, i ) - if ( Vec_IntEntry(vTimes, Gia_ObjFaninId0p(p, pObj)) > Period ) + if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > Period ) + return 0; + Gia_ManForEachObj( p, pObj, i ) + if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > 2*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 ) +int Gia_ManSifMapComb( 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 ); + Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 ); Gia_ManForEachAnd( p, pObj, i ) - Gia_ManCutOne( p, i, vCuts, vTimes, nSize ); + Gia_ManSifCutOne( 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 ) +void Gia_ManSifPrintTimes( 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]++; + int i, Value, Pos[256] = {0}, Neg[256] = {0}; + Gia_ManForEachLut( p, i ) + { + Value = Gia_ManSifTimeToCount( Vec_IntEntry(vTimes, i), Period ); + Value = Abc_MinInt( Value, 255 ); + Value = Abc_MaxInt( Value, -255 ); + if ( Value >= 0 ) + Pos[Value]++; else - Neg[(-Time + Period-1)/Period]++; + Neg[-Value]++; } printf( "Statistics: " ); - for ( i = 15; i > 0; i-- ) + for ( i = 255; i > 0; i-- ) if ( Neg[i] ) printf( " -%d=%d", i, Neg[i] ); - for ( i = 0; i < 16; i++ ) + for ( i = 0; i < 256; 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 Gia_ManSifDeriveMapping_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vCuts, int nSize ) { - int nIters, nSize = nLutSize+1; // (2+1+nSize)*4=40 bytes/node + int i, * pCut, Area = 1; + if ( !Gia_ObjIsAnd(pObj) ) + return 0; + if ( Gia_ObjUpdateTravIdCurrent(p, pObj) ) + return 0; + pCut = Vec_IntEntryP( vCuts, Gia_ObjId(p, pObj)*nSize ); + for ( i = 1; i <= pCut[0]; i++ ) + Area += Gia_ManSifDeriveMapping_rec( p, Gia_ManObj(p, pCut[i] >> 8), vCuts, nSize ); + Vec_IntWriteEntry( p->vMapping, Gia_ObjId(p, pObj), Vec_IntSize(p->vMapping) ); + Vec_IntPush( p->vMapping, pCut[0] ); + for ( i = 1; i <= pCut[0]; i++ ) + { + Gia_Obj_t * pObj = Gia_ManObj(p, pCut[i] >> 8); + assert( !Gia_ObjIsAnd(pObj) || Gia_ObjIsLut(p, pCut[i] >> 8) ); + Vec_IntPush( p->vMapping, pCut[i] >> 8 ); + } + Vec_IntPush( p->vMapping, -1 ); + return Area; +} +int Gia_ManSifDeriveMapping( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int fVerbose ) +{ + Gia_Obj_t * pObj; int i, nArea = 0; + if ( p->vMapping != NULL ) + { + printf( "Removing available combinational mapping.\n" ); + Vec_IntFreeP( &p->vMapping ); + } + assert( p->vMapping == NULL ); + p->vMapping = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_ManIncrementTravId( p ); + Gia_ManForEachCo( p, pObj, i ) + nArea += Gia_ManSifDeriveMapping_rec( p, Gia_ObjFanin0(pObj), vCuts, nLutSize+1 ); + return nArea; +} +Gia_Man_t * Gia_ManSifPerform( Gia_Man_t * p, int nLutSize, int fEvalOnly, int fVerbose ) +{ + Gia_Man_t * pNew = NULL; + int nIters, Status, 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 ); + int Upper = Gia_ManSifMapComb( p, vCuts, vTimes, nLutSize ); + int CombD = Upper; if ( fVerbose && Gia_ManRegNum(p) ) printf( "Clock period %2d is %s\n", Lower, 0 ? "Yes" : "No " ); if ( fVerbose && Gia_ManRegNum(p) ) @@ -225,7 +602,7 @@ Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose ) while ( Gia_ManRegNum(p) > 0 && Upper - Lower > 1 ) { int Middle = (Upper + Lower) / 2; - int Status = Gia_ManCheckPeriod( p, vCuts, vTimes, nLutSize, Middle, &nIters ); + int Status = Gia_ManSifCheckPeriod( p, vCuts, vTimes, nLutSize, Middle, &nIters ); if ( Status ) Upper = Middle; else @@ -234,18 +611,34 @@ Gia_Man_t * Gia_ManTestSif( Gia_Man_t * p, int nLutSize, int fVerbose ) printf( "Clock period %2d is %s after %d iterations\n", Middle, Status ? "Yes" : "No ", nIters ); } if ( fVerbose ) - printf( "Clock period = %2d ", Upper ); + printf( "Best period = <<%d>> (%.2f %%) ", Upper, (float)(100.0*(CombD-Upper)/CombD) ); 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 ); + if ( Upper == CombD ) + { + Vec_IntFree( vCuts ); + Vec_IntFree( vTimes ); + printf( "Combinational delay (%d) cannot be improved.\n", CombD ); + return Gia_ManDup( p ); + } + Status = Gia_ManSifCheckPeriod( p, vCuts, vTimes, nLutSize, Upper, &nIters ); + assert( Status ); + Status = Gia_ManSifDeriveMapping( p, vCuts, vTimes, nLutSize, Upper, fVerbose ); + if ( fEvalOnly ) + { + printf( "Optimized level %2d (%6.2f %% less than comb level %2d). LUT size = %d. Area estimate = %d.\n", + Upper, (float)(100.0*(CombD-Upper)/CombD), CombD, nLutSize, Gia_ManSifArea(p, vCuts, nLutSize+1) ); + printf( "The command is invoked in the evaluation mode. Retiming is not performed.\n" ); + } + else + pNew = Gia_ManSifTransform( p, vCuts, vTimes, nLutSize, Upper, fVerbose ); Vec_IntFree( vCuts ); Vec_IntFree( vTimes ); - return NULL; + return pNew; } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 3729dcf3b..6a728884a 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40539,11 +40539,11 @@ usage: ***********************************************************************/ 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 ); + extern Gia_Man_t * Gia_ManSifPerform( Gia_Man_t * p, int nLutSize, int fEvalOnly, int fVerbose ); Gia_Man_t * pNew; - int c, nLutSize = 6, fVerbose = 0; + int c, nLutSize = 6, fEvalOnly = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Kvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Kevh" ) ) != EOF ) { switch ( c ) { @@ -40561,6 +40561,9 @@ int Abc_CommandAbc9Sif( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } break; + case 'e': + fEvalOnly ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -40574,15 +40577,16 @@ int Abc_CommandAbc9Sif( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Empty GIA network.\n" ); return 1; } - pNew = Gia_ManTestSif( pAbc->pGia, nLutSize, fVerbose ); + pNew = Gia_ManSifPerform( pAbc->pGia, nLutSize, fEvalOnly, fVerbose ); if ( pNew != NULL ) Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: &sif [-K num] [-vh]\n" ); + Abc_Print( -2, "usage: &sif [-K num] [-evh]\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-e : toggles the evaluation mode [default = %s]\n", fEvalOnly? "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"); return 1; diff --git a/src/base/abci/abcSat.c b/src/base/abci/abcSat.c index f0ed15320..85ada2648 100644 --- a/src/base/abci/abcSat.c +++ b/src/base/abci/abcSat.c @@ -22,6 +22,8 @@ #include "base/main/main.h" #include "base/cmd/cmd.h" #include "sat/bsat/satSolver.h" +#include "aig/gia/gia.h" +#include "aig/gia/giaAig.h" #ifdef ABC_USE_CUDD #include "bdd/extrab/extraBdd.h" @@ -143,6 +145,36 @@ sat_solver_store_free( pSat ); return RetValue; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int * Abc_NtkSolveGiaMiter( Gia_Man_t * p ) +{ + extern Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan ); + int RetValue = 0; + int * pResult = NULL; + Abc_Ntk_t * pNtk; + Aig_Man_t * pMan; + pMan = Gia_ManToAig( p, 0 ); + pNtk = Abc_NtkFromAigPhase( pMan ); + pNtk->pName = Extra_UtilStrsav(p->pName); + Aig_ManStop( pMan ); + RetValue = Abc_NtkMiterSat( pNtk, 1000000, 0, 0, NULL, NULL ); + if ( RetValue == 0 ) // sat + pResult = pNtk->pModel, pNtk->pModel = NULL; + Abc_NtkDelete( pNtk ); + return pResult; +} + + /**Function************************************************************* Synopsis [Returns the array of CI IDs.]