30#define SAIG_DIFF_VALUES 8
31#define SAIG_UNDEF_VALUE 0x1ffffffe
87static inline int Saig_MvObjFaninC0(
Saig_MvObj_t * pObj ) {
return pObj->
iFan0 & 1; }
88static inline int Saig_MvObjFaninC1(
Saig_MvObj_t * pObj ) {
return pObj->
iFan1 & 1; }
89static inline int Saig_MvObjFanin0(
Saig_MvObj_t * pObj ) {
return pObj->
iFan0 >> 1; }
90static inline int Saig_MvObjFanin1(
Saig_MvObj_t * pObj ) {
return pObj->
iFan1 >> 1; }
92static inline int Saig_MvConst0() {
return 1; }
93static inline int Saig_MvConst1() {
return 0; }
94static inline int Saig_MvConst(
int c ) {
return !c; }
97static inline int Saig_MvIsConst0(
int iNode ) {
return iNode == 1; }
98static inline int Saig_MvIsConst1(
int iNode ) {
return iNode == 0; }
99static inline int Saig_MvIsConst(
int iNode ) {
return iNode < 2; }
100static inline int Saig_MvIsUndef(
int iNode ) {
return iNode ==
SAIG_UNDEF_VALUE; }
102static inline int Saig_MvRegular(
int iNode ) {
return (iNode & ~01); }
103static inline int Saig_MvNot(
int iNode ) {
return (iNode ^ 01); }
104static inline int Saig_MvNotCond(
int iNode,
int c ) {
return (iNode ^ (c)); }
105static inline int Saig_MvIsComplement(
int iNode ) {
return (
int)(iNode & 01); }
107static inline int Saig_MvLit2Var(
int iNode ) {
return (iNode >> 1); }
108static inline int Saig_MvVar2Lit(
int iVar ) {
return (iVar << 1); }
109static inline int Saig_MvLev(
Saig_MvMan_t *
p,
int iNode ) {
return p->pLevels[iNode >> 1]; }
112#define Saig_MvManForEachObj( pAig, pEntry ) \
113 for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ )
135 *pvFlops = Vec_PtrAlloc( Aig_ManRegNum(
p) );
141 if ( Aig_ObjIsCi(pObj) || i == 0 )
143 if ( Saig_ObjIsLo(
p, pObj) )
145 pEntry->
iFan0 = (Saig_ObjLoToLi(
p, pObj)->Id << 1);
147 Vec_PtrPush( *pvFlops, pEntry );
151 pEntry->
iFan0 = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj);
152 if ( Aig_ObjIsCo(pObj) )
154 assert( Aig_ObjIsNode(pObj) );
155 pEntry->
iFan1 = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj);
157 pEntry = pAig + Aig_ManObjNumMax(
p);
173static inline int Saig_MvCreateObj(
Saig_MvMan_t *
p,
int iFan0,
int iFan1 )
176 if (
p->nObjs ==
p->nObjsAlloc )
179 p->pLevels =
ABC_REALLOC(
unsigned char,
p->pLevels, 2*
p->nObjsAlloc );
182 pNode =
p->pAigNew +
p->nObjs;
183 pNode->
iFan0 = iFan0;
184 pNode->
iFan1 = iFan1;
186 if ( iFan0 || iFan1 )
187 p->pLevels[
p->nObjs] = 1 + Abc_MaxInt( Saig_MvLev(
p, iFan0), Saig_MvLev(
p, iFan1) );
189 p->pLevels[
p->nObjs] = 0,
p->nPis++;
208 assert( Aig_ManRegNum(pAig) > 0 );
213 p->nStatesMax = 2 * nFramesSatur + 100;
216 p->nFlops = Aig_ManRegNum(pAig);
219 p->nTStatesSize = Abc_PrimeCudd(
p->nStatesMax );
222 p->vStates = Vec_PtrAlloc(
p->nStatesMax );
223 Vec_PtrPush(
p->vStates, NULL );
226 p->pRegsValues[0] =
ABC_ALLOC(
int,
p->nValuesMax *
p->nFlops );
227 for ( i = 1; i <
p->nFlops; i++ )
228 p->pRegsValues[i] =
p->pRegsValues[i-1] +
p->nValuesMax;
230 p->vTired = Vec_PtrAlloc( 100 );
232 p->nObjsAlloc = 1000000;
234 p->nTNodesSize = Abc_PrimeCudd(
p->nObjsAlloc / 3 );
236 p->pLevels =
ABC_ALLOC(
unsigned char,
p->nObjsAlloc );
237 Saig_MvCreateObj(
p, 0, 0 );
255 Vec_PtrFree(
p->vStates );
256 Vec_IntFreeP( &
p->vXFlops );
257 Vec_PtrFree(
p->vFlops );
258 Vec_PtrFree(
p->vTired );
282static inline int Saig_MvHash(
int iFan0,
int iFan1,
int TableSize )
286 Key ^= Saig_MvLit2Var(iFan0) * 7937;
287 Key ^= Saig_MvLit2Var(iFan1) * 2971;
288 Key ^= Saig_MvIsComplement(iFan0) * 911;
289 Key ^= Saig_MvIsComplement(iFan1) * 353;
290 return (
int)(Key % TableSize);
304static inline int * Saig_MvTableFind(
Saig_MvMan_t *
p,
int iFan0,
int iFan1 )
307 int * pPlace =
p->pTNodes + Saig_MvHash( iFan0, iFan1,
p->nTNodesSize );
308 for ( pEntry = (*pPlace)?
p->pAigNew + *pPlace : NULL; pEntry;
309 pPlace = &pEntry->
iNext, pEntry = (*pPlace)?
p->pAigNew + *pPlace : NULL )
310 if ( pEntry->
iFan0 == iFan0 && pEntry->
iFan1 == iFan1 )
326static inline int Saig_MvAnd(
Saig_MvMan_t *
p,
int iFan0,
int iFan1,
int fFirst )
328 if ( iFan0 == iFan1 )
330 if ( iFan0 == Saig_MvNot(iFan1) )
331 return Saig_MvConst0();
332 if ( Saig_MvIsConst(iFan0) )
333 return Saig_MvIsConst1(iFan0) ? iFan1 : Saig_MvConst0();
334 if ( Saig_MvIsConst(iFan1) )
335 return Saig_MvIsConst1(iFan1) ? iFan0 : Saig_MvConst0();
336 if ( Saig_MvIsUndef(iFan0) || Saig_MvIsUndef(iFan1) )
337 return Saig_MvUndef();
343 return Saig_MvUndef();
353 pPlace = Saig_MvTableFind(
p, iFan0, iFan1 );
356 if ( pPlace >= (
int*)
p->pAigNew && pPlace < (
int*)(
p->pAigNew +
p->nObjsAlloc) )
358 int iPlace = pPlace - (
int*)
p->pAigNew;
359 int iNode = Saig_MvCreateObj(
p, iFan0, iFan1 );
360 ((
int*)
p->pAigNew)[iPlace] = iNode;
361 return Saig_MvVar2Lit( iNode );
364 *pPlace = Saig_MvCreateObj(
p, iFan0, iFan1 );
366 return Saig_MvVar2Lit( *pPlace );
384 if ( Saig_MvIsUndef( pObj0->
Value ) )
385 return Saig_MvUndef();
386 return Saig_MvNotCond( pObj0->
Value, Saig_MvObjFaninC0(pObj) );
391 if ( Saig_MvIsUndef( pObj1->
Value ) )
392 return Saig_MvUndef();
393 return Saig_MvNotCond( pObj1->
Value, Saig_MvObjFaninC1(pObj) );
411 printf(
"%3d : ", Iter );
417 printf(
"%5d", pEntry->
Value );
441 pEntry->
Value = Saig_MvAnd(
p,
442 Saig_MvSimulateValue0(
p->pAigOld, pEntry),
443 Saig_MvSimulateValue1(
p->pAigOld, pEntry), fFirst );
446 pEntry->
Value = Saig_MvSimulateValue0(
p->pAigOld, pEntry);
449 if ( pEntry->
iFan1 == 0 )
452 pEntry->
Value = Saig_MvVar2Lit( Saig_MvCreateObj(
p, 0, 0 ) );
462 pEntry->
Value = Saig_MvConst1();
468 pEntry->
Value = Saig_MvSimulateValue0(
p->pAigOld, pEntry );
485 static int s_SPrimes[16] = {
505 for ( i = 0; i < nFlops; i++ )
506 uHash ^= pState[i] * s_SPrimes[i & 0xF];
507 return (
int)(uHash % TableSize);
521static inline unsigned * Saig_MvSimTableFind(
Saig_MvMan_t *
p,
unsigned * pState )
524 unsigned * pPlace =
p->pTStates +
Saig_MvSimHash( pState+1,
p->nFlops,
p->nTStatesSize );
525 for ( pEntry = (*pPlace)? (
unsigned *)Vec_PtrEntry(
p->vStates, *pPlace) : NULL; pEntry;
526 pPlace = pEntry, pEntry = (*pPlace)? (
unsigned *)Vec_PtrEntry(
p->vStates, *pPlace) : NULL )
527 if (
memcmp( pEntry+1, pState+1,
sizeof(
int)*
p->nFlops ) == 0 )
546 unsigned * pState, * pPlace;
551 pState[i+1] = pEntry->
Value;
552 pPlace = Saig_MvSimTableFind(
p, pState );
555 *pPlace = Vec_PtrSize(
p->vStates );
556 Vec_PtrPush(
p->vStates, pState );
575 int i, k, j,
nTotal = 0, iFlop;
576 Vec_Int_t * vUniques = Vec_IntAlloc( 100 );
577 Vec_Int_t * vCounter = Vec_IntAlloc( 100 );
580 if (
p->pRegsUndef[i] == 0 )
582 printf(
"The number of registers that never became undef = %d. (Total = %d.)\n",
nTotal,
p->nFlops );
585 if (
p->pRegsUndef[i] )
590 if ( pState[iFlop+1] != pState[i+1] )
592 if ( j == Vec_PtrSize(
p->vStates) )
594 Vec_IntAddToEntry( vCounter, k, 1 );
598 if ( k == Vec_IntSize(vUniques) )
600 Vec_IntPush( vUniques, i );
601 Vec_IntPush( vCounter, 1 );
606 printf(
"FLOP %5d : (%3d) ", iFlop, Vec_IntEntry(vCounter,i) );
622 printf(
"%d", pState[iFlop+1] );
629 Vec_IntFree( vUniques );
630 Vec_IntFree( vCounter );
649 vXFlops = Vec_IntStart(
p->nFlops );
652 for ( k = 0; k <
p->nFlops; k++ )
653 if ( Saig_MvIsUndef(pState[k+1]) )
654 Vec_IntWriteEntry( vXFlops, k, 1 );
676 vValues = Vec_IntAlloc( 100 );
679 Vec_IntPush( vValues, pState[iFlop+1] );
683 assert( Saig_MvIsConst0( Vec_IntEntry(vValues,0) ) );
685 for ( Per = 0; Per < Vec_IntSize(vValues)/2; Per++ )
689 if ( !Saig_MvIsConst0(Entry) )
691 if ( Per == Vec_IntSize(vValues) )
695 if ( Saig_MvIsConst0(Entry) )
697 if ( Per == Vec_IntSize(vValues) )
700 assert( Saig_MvIsConst0( Vec_IntEntry(vValues,Per) ) );
701 for ( k = Per; k < Vec_IntSize(vValues); k++ )
702 if ( Vec_IntEntry(vValues, k-Per) != Vec_IntEntry(vValues, k) )
704 if ( k < Vec_IntSize(vValues) )
706 Vec_IntFree( vValues );
710 Vec_IntFree( vValues );
731 vConst0 = Vec_IntAlloc(
p->nFlops );
732 vBinary = Vec_IntAlloc(
p->nFlops );
733 for ( k = 0; k <
p->nFlops; k++ )
739 if ( !Saig_MvIsConst0(pState[k+1]) )
741 if ( Saig_MvIsUndef(pState[k+1]) )
744 if ( i < Vec_PtrSize(
p->vStates) )
748 Vec_IntPush( vConst0, k );
750 Vec_IntPush( vBinary, k );
774 vOscils = Vec_IntAlloc( 100 );
777 Vec_IntPush( vOscils, Entry );
778 Vec_IntFree( vBinary );
795 Vec_Int_t * vConst0, * vOscils, * vXFlops;
799 vXFlops = Vec_IntAlloc(
p->nFlops );
800 Vec_IntFill( vXFlops,
p->nFlops, 1 );
802 Vec_IntWriteEntry( vXFlops, Entry, 0 );
804 Vec_IntWriteEntry( vXFlops, Entry, 0 );
805 Vec_IntFree( vOscils );
806 Vec_IntFree( vConst0 );
827 int i, k, j, FlopK, FlopJ;
828 int Counter1 = 0, Counter2 = 0;
830 vMap = Vec_PtrAlloc( Aig_ManCiNum(
p->pAig) );
832 Vec_PtrPush( vMap, pObj );
838 Vec_PtrWriteEntry( vMap, Saig_ManPiNum(
p->pAig) + FlopK, Aig_ManConst0(
p->pAig) );
841 Vec_IntFree( vConst0 );
851 if ( pState[FlopK+1] != pState[FlopJ+1] )
853 if ( i < Vec_PtrSize(
p->vStates) )
856 Vec_PtrWriteEntry( vMap, Saig_ManPiNum(
p->pAig) + FlopJ, Saig_ManLo(
p->pAig, FlopK) );
857 Vec_IntWriteEntry( vBinValued, j, -1 );
861 printf(
"Detected %d const0 flops and %d pairs of equiv binary flops.\n", Counter1, Counter2 );
862 Vec_IntFree( vBinValued );
863 if ( Counter1 == 0 && Counter2 == 0 )
864 Vec_PtrFreeP( &vMap );
886 assert( nFramesSymb >= 1 && nFramesSymb <= nFramesSatur );
891ABC_PRT(
"Constructing the problem", Abc_Clock() - clk );
895 pEntry->
Value = Saig_MvConst0();
903 if ( f == nFramesSatur )
906 printf(
"Beginning to saturate simulation after %d frames\n", f );
910 if ( f == 2 * nFramesSatur )
913 printf(
"Aggressively saturating simulation after %d frames\n", f );
914 Vec_IntFree(
p->vXFlops );
921 if ( Vec_IntEntry(
p->vXFlops, i ) )
933 printf(
"Converged after %d frames with lasso in state %d. Cycle = %d.\n", f+1, iState-1, f+2-iState );
940ABC_PRT(
"Multi-valued simulation", Abc_Clock() - clk );
#define ABC_ALLOC(type, num)
#define ABC_REALLOC(type, obj, num)
#define ABC_CALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
char * Aig_MmFixedEntryFetch(Aig_MmFixed_t *p)
#define Aig_ManForEachObj(p, pObj, i)
#define Aig_ManForEachCi(p, pObj, i)
ITERATORS ///.
struct Aig_Obj_t_ Aig_Obj_t
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Aig_MmFixed_t * Aig_MmFixedStart(int nEntrySize, int nEntriesMax)
FUNCTION DEFINITIONS ///.
struct Aig_MmFixed_t_ Aig_MmFixed_t
void Aig_MmFixedStop(Aig_MmFixed_t *p, int fVerbose)
int nTotal
DECLARATIONS ///.
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
void Saig_MvManPostProcess(Saig_MvMan_t *p, int iState)
int Saig_MvSaveState(Saig_MvMan_t *p)
Saig_MvObj_t * Saig_ManCreateReducedAig(Aig_Man_t *p, Vec_Ptr_t **pvFlops)
FUNCTION DEFINITIONS ///.
void Saig_MvPrintState(int Iter, Saig_MvMan_t *p)
Vec_Ptr_t * Saig_MvManDeriveMap(Saig_MvMan_t *p, int fVerbose)
Vec_Int_t * Saig_MvManCreateNextSkip(Saig_MvMan_t *p)
Vec_Int_t * Saig_MvManFindOscilators(Saig_MvMan_t *p, Vec_Int_t **pvConst0)
void Saig_MvSimulateFrame(Saig_MvMan_t *p, int fFirst, int fVerbose)
int Saig_MvSimHash(unsigned *pState, int nFlops, int TableSize)
Vec_Int_t * Saig_MvManFindXFlops(Saig_MvMan_t *p)
Vec_Int_t * Saig_MvManFindConstBinaryFlops(Saig_MvMan_t *p, Vec_Int_t **pvBinary)
struct Saig_MvMan_t_ Saig_MvMan_t
struct Saig_MvAnd_t_ Saig_MvAnd_t
#define SAIG_DIFF_VALUES
DECLARATIONS ///.
Vec_Ptr_t * Saig_MvManSimulate(Aig_Man_t *pAig, int nFramesSymb, int nFramesSatur, int fVerbose, int fVeryVerbose)
int Saig_MvManCheckOscilator(Saig_MvMan_t *p, int iFlop)
#define Saig_MvManForEachObj(pAig, pEntry)
void Saig_MvManStop(Saig_MvMan_t *p)
Saig_MvMan_t * Saig_MvManStart(Aig_Man_t *pAig, int nFramesSatur)
struct Saig_MvObj_t_ Saig_MvObj_t
int nRValues[SAIG_DIFF_VALUES+1]
Aig_MmFixed_t * pMemStates
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
#define Vec_PtrForEachEntryStart(Type, vVec, pEntry, i, Start)
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.