summaryrefslogtreecommitdiffstats
path: root/src/base/abci/abcLut.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/abci/abcLut.c')
-rw-r--r--src/base/abci/abcLut.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/base/abci/abcLut.c b/src/base/abci/abcLut.c
index edc2b7de..8dc84ba0 100644
--- a/src/base/abci/abcLut.c
+++ b/src/base/abci/abcLut.c
@@ -783,6 +783,164 @@ int Abc_NodeDecomposeStep( Abc_ManScl_t * p )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Performs specialized mapping.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static word s__Truths6[6] = {
+ ABC_CONST(0xAAAAAAAAAAAAAAAA),
+ ABC_CONST(0xCCCCCCCCCCCCCCCC),
+ ABC_CONST(0xF0F0F0F0F0F0F0F0),
+ ABC_CONST(0xFF00FF00FF00FF00),
+ ABC_CONST(0xFFFF0000FFFF0000),
+ ABC_CONST(0xFFFFFFFF00000000)
+};
+word Abc_ObjComputeTruth( Abc_Obj_t * pObj, Vec_Int_t * vSupp )
+{
+ int Index; word t0, t1, tc;
+ assert( Vec_IntSize(vSupp) <= 6 );
+ if ( (Index = Vec_IntFind(vSupp, Abc_ObjId(pObj))) >= 0 )
+ return s__Truths6[Index];
+ assert( Abc_ObjIsNode(pObj) );
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ return Abc_NodeIsConst0(pObj) ? (word)0 : ~(word)0;
+ assert( Abc_ObjFaninNum(pObj) == 3 );
+ t0 = Abc_ObjComputeTruth( Abc_ObjFanin(pObj, 2), vSupp );
+ t1 = Abc_ObjComputeTruth( Abc_ObjFanin(pObj, 1), vSupp );
+ tc = Abc_ObjComputeTruth( Abc_ObjFanin(pObj, 0), vSupp );
+ return (tc & t1) | (~tc & t0);
+}
+Abc_Obj_t * Abc_NtkSpecialMap_rec( Abc_Ntk_t * pNew, Abc_Obj_t * pObj, Vec_Wec_t * vSupps, Vec_Int_t * vCover )
+{
+ if ( pObj->pCopy )
+ return pObj->pCopy;
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ return NULL;
+ assert( Abc_ObjFaninNum(pObj) == 3 );
+ if ( pObj->fMarkA || pObj->fMarkB )
+ {
+ Abc_Obj_t * pFan0 = Abc_NtkSpecialMap_rec( pNew, Abc_ObjFanin(pObj, 2), vSupps, vCover );
+ Abc_Obj_t * pFan1 = Abc_NtkSpecialMap_rec( pNew, Abc_ObjFanin(pObj, 1), vSupps, vCover );
+ Abc_Obj_t * pFanC = Abc_NtkSpecialMap_rec( pNew, Abc_ObjFanin(pObj, 0), vSupps, vCover );
+ if ( pFan0 == NULL )
+ pFan0 = Abc_NodeIsConst0(Abc_ObjFanin(pObj, 2)) ? Abc_NtkCreateNodeConst0(pNew) : Abc_NtkCreateNodeConst1(pNew);
+ if ( pFan1 == NULL )
+ pFan1 = Abc_NodeIsConst0(Abc_ObjFanin(pObj, 1)) ? Abc_NtkCreateNodeConst0(pNew) : Abc_NtkCreateNodeConst1(pNew);
+ pObj->pCopy = Abc_NtkCreateNodeMux( pNew, pFanC, pFan1, pFan0 );
+ pObj->pCopy->fMarkA = pObj->fMarkA;
+ pObj->pCopy->fMarkB = pObj->fMarkB;
+ }
+ else
+ {
+ Abc_Obj_t * pTemp; int i; word Truth;
+ Vec_Int_t * vSupp = Vec_WecEntry( vSupps, Abc_ObjId(pObj) );
+ Abc_NtkForEachObjVec( vSupp, pObj->pNtk, pTemp, i )
+ Abc_NtkSpecialMap_rec( pNew, pTemp, vSupps, vCover );
+ pObj->pCopy = Abc_NtkCreateNode( pNew );
+ Abc_NtkForEachObjVec( vSupp, pObj->pNtk, pTemp, i )
+ Abc_ObjAddFanin( pObj->pCopy, pTemp->pCopy );
+ Truth = Abc_ObjComputeTruth( pObj, vSupp );
+ pObj->pCopy->pData = Abc_SopCreateFromTruthIsop( (Mem_Flex_t *)pNew->pManFunc, Vec_IntSize(vSupp), &Truth, vCover );
+ assert( Abc_SopGetVarNum((char *)pObj->pCopy->pData) == Vec_IntSize(vSupp) );
+ }
+ return pObj->pCopy;
+}
+Abc_Ntk_t * Abc_NtkSpecialMapping( Abc_Ntk_t * pNtk, int fVerbose )
+{
+ Abc_Ntk_t * pNtkNew;
+ Vec_Int_t * vCover = Vec_IntAlloc( 1 << 16 );
+ Vec_Wec_t * vSupps = Vec_WecStart( Abc_NtkObjNumMax(pNtk) );
+ Abc_Obj_t * pObj, * pFan0, * pFan1, * pFanC; int i, Count[2] = {0};
+ Abc_NtkForEachCi( pNtk, pObj, i )
+ Vec_IntPush( Vec_WecEntry(vSupps, i), i );
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ Vec_Int_t * vSupp = Vec_WecEntry(vSupps, i);
+ if ( Abc_ObjFaninNum(pObj) == 0 )
+ continue;
+ assert( Abc_ObjFaninNum(pObj) == 3 );
+ pFan0 = Abc_ObjFanin( pObj, 2 );
+ pFan1 = Abc_ObjFanin( pObj, 1 );
+ pFanC = Abc_ObjFanin0( pObj );
+ assert( Abc_ObjIsCi(pFanC) );
+ if ( pFan0->fMarkA && pFan1->fMarkA )
+ {
+ pObj->fMarkB = 1;
+ Vec_IntPush( vSupp, Abc_ObjId(pObj) );
+ continue;
+ }
+ Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Abc_ObjId(pFan0)), Vec_WecEntry(vSupps, Abc_ObjId(pFan1)), vSupp );
+ assert( Vec_IntFind(vSupp, Abc_ObjId(pFanC)) == -1 );
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFanC) );
+ if ( Vec_IntSize(vSupp) <= 6 )
+ continue;
+ Vec_IntClear( vSupp );
+ if ( !pFan0->fMarkA && !pFan1->fMarkA )
+ {
+ pObj->fMarkA = 1;
+ Vec_IntPush( vSupp, Abc_ObjId(pObj) );
+ }
+ else
+ {
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFan0) );
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFan1) );
+ Vec_IntPushOrder( vSupp, Abc_ObjId(pFanC) );
+ }
+ }
+
+ if ( fVerbose )
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ printf( "Node %4d : ", i );
+ if ( pObj->fMarkA )
+ printf( " MarkA " );
+ else
+ printf( " " );
+ if ( pObj->fMarkB )
+ printf( " MarkB " );
+ else
+ printf( " " );
+ Vec_IntPrint( Vec_WecEntry(vSupps, i) );
+ }
+
+ Abc_NtkCleanCopy( pNtk );
+ pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
+ Abc_NtkForEachCo( pNtk, pObj, i )
+ if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 0 )
+ Abc_ObjFanin0(pObj)->pCopy = Abc_NodeIsConst0(Abc_ObjFanin0(pObj)) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew);
+ else
+ Abc_NtkSpecialMap_rec( pNtkNew, Abc_ObjFanin0(pObj), vSupps, vCover );
+ Abc_NtkFinalize( pNtk, pNtkNew );
+ Abc_NtkCleanMarkAB( pNtk );
+ Vec_WecFree( vSupps );
+ Vec_IntFree( vCover );
+
+ Abc_NtkForEachNode( pNtkNew, pObj, i )
+ {
+ Count[0] += pObj->fMarkA,
+ Count[1] += pObj->fMarkB;
+ pObj->fPersist = pObj->fMarkA | pObj->fMarkB;
+ pObj->fMarkA = pObj->fMarkB = 0;
+ }
+ //printf( "Total = %3d. Nodes = %3d. MarkA = %3d. MarkB = %3d.\n", Abc_NtkNodeNum(pNtkNew),
+ // Abc_NtkNodeNum(pNtkNew) - Count[0] - Count[1], Count[0], Count[1] );
+
+ if ( !Abc_NtkCheck( pNtkNew ) )
+ {
+ printf( "Abc_NtkSpecialMapping: The network check has failed.\n" );
+ Abc_NtkDelete( pNtkNew );
+ return NULL;
+ }
+ return pNtkNew;
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////